Preamble

This document serves as a summary of the data analysis conducted during my PhD thesis. It is structured chronologically to emphasize decision making based on the previous results. The basic question was if UV radiation influences tumor growth beyond initiation e.g. by induction of genomic changes or epigenetic alterations resulting in tumor progression and metastasis of cutaneous squamous cell carcinoma (cSCC). All miRNAs in the following study were human miRNAs. Data is available at:

Loading of required packages

# data wrangling and basic visualization
library(tidyverse)
library(ggpubr)
library(data.table)
library(gtools)
# statistics
library(rstatix)
library(EnvStats) 
# Heatmap
library(ComplexHeatmap)
library(circlize)
# PCA
library(FactoMineR)
library(factoextra)
# pathway analysis
library(RBiomirGS)
# parallel computing and access of internet data
library(devtools)
library(doParallel)

# source custom R functions
source_url("https://raw.githubusercontent.com/MBender1992/base_scripts/Marc/R_functions.R")  

1. Screening for UV induced miRNAs

1.1 Experimental setup and data ingestion

In a first step we screened 51 manually curated miRNAs associated with cSCC or other epithelial tumors for UV induced changes. To this end, five different cancer cell lines (SCL-II, Met-1, Met-4, SCC-12, SCC-13; Fig. 1) were grown under standard cell culture conditions with DMEM (Met-1,Met-4, SCL-II) or FAD (SCC-12, SCC-13) as cell culture media. Cells were grown to 80 % confluency and exposed to 103 kJ/m² (physical doses: 246.01 J/m² UVB (280-315 nm); 12.50 kJ/m² UVA (315-400 nm); 28.03 kJ/m² VIS (400-750 nm); 61.74 kJ/m² IR-A (750-1200 nm)) sunlight-equivalent radiation (SER) with a custom-built irradiation device (KAUVIR: https://www.fona.de/de/massnahmen/foerdermassnahmen/strahlenforschung.php). The cells were treated eight times with this dose over a time course of 4 weeks (irradiation twice a week) to simulate a chronic UV exposure. For the analysis 4 biological replicates were used.

Fig. 1: Cell line characteristics of the tumor cell lines used in this study. The cell lines exhibit different levels of differentiation with SCC-13 being highly differentiated and SCL-II being undifferentiated. p53 mutations are present in all cell lines except Met-1 and Met-4. Met-1 and Met-4 are cell lines from the same patient in different stages of the tumor.)

Fig. 1: Cell line characteristics of the tumor cell lines used in this study. The cell lines exhibit different levels of differentiation with SCC-13 being highly differentiated and SCL-II being undifferentiated. p53 mutations are present in all cell lines except Met-1 and Met-4. Met-1 and Met-4 are cell lines from the same patient in different stages of the tumor.)

After irradiation, cells were harvested and subjected to FirePlex immunoassay (abcam; https://www.abcam.com/nav/multiplex-assays/fireplex-immunoassays) to detect changes in miRNA expression using barcode-labelled probes. Data was imported to the complimentary workbench software and normalized to the 12 most stable miRNAs using the built-in algorithm.

normalizers <- c("miR-23a-3p","miR-23b-3p", "miR-24-3p", "miR-26a-3p", "miR-30b-3p", "miR-22-3p", "miR-16-5p", "miR-221-3p", "miR-15a-3p", "miR-29a-3p", "let-7f-5p", "miR-29c-3p")
normalizers

Subsequently, data was imported into R using the following function, to exclude miRNAs with a median expression below an arbitrary threshold, convert data from wide to tidy data and add a column with log2-transformed values as expression data follows a log-normal distribution (Beal 2017, https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=7991639) :

load_Fireplex_data_PhD <- function(filename, threshold)
{
  # check if required package is installed and load it
  if (!require(dplyr)) install.packages("dplyr")
  library(dplyr)
  
  #load data and change hyphens to underscores so r does not confuse a hyphen with minus
  dat <- read_csv(filename)
  names(dat) <- str_replace_all(names(dat), "-","_")
  # clean up the data, convert to tidy format and replace negative expression values with 0 as expression        cannot be negative
  dat_f <- dat %>% 
    select(-Messung) %>%
    filter(cell_line != "HaCaT") %>%
    gather(miRNA, expression, -c(ID,cell_line, Irradiation)) %>% 
    mutate(expression = ifelse(expression < 0, 0, expression))  
  # index miRNAs with a median expression below the threshold
  ind <- dat_f %>%
    group_by(miRNA) %>%
    filter(median(expression, na.rm=TRUE) <= threshold) %>%
    .$miRNA %>% 
    unique() 
  # omit indexed miRNAs and add log2-transformed expression values 
  dat_f %>% 
    filter(!miRNA %in% ind) %>%
    mutate(log_exp = log2(expression+1)) %>%
    mutate(miRNA = str_replace_all(miRNA, "hsa_", "")) %>%
    mutate(miRNA = str_replace_all(miRNA, "_","-")) %>%
    mutate(cell_line = str_replace_all(cell_line, "-","_"))
}

url_file <- "https://raw.githubusercontent.com/MBender1992/PhD/Marc/Data/PhD_MB_FirePlex_chronic_irr_20190620.csv" 
dat <-  load_Fireplex_data_PhD(filename = url(url_file), threshold = 2.5)
dat

The threshold was set to 2.5 (a.u.) as this is the detection limit of the assay as indicated by the manufacturers instructions. After applying this threshold 40 out of the intially 51 examined miRNAs remained in the analysis.

1.2 Principal component analysis (PCA)

1.2.1 Theoretical Background

Note: Explanation from Statquest (YouTube) concerning PCA. An illustration of principal components for an example with 2 variables:

Data is plotted as var1 vs var2 (var1 on the x-axis, var2 on the y-axis). The center of this data is calculated and the data points are shifted so the center is at the origin (0,0). However, the relationship of the data points due to this rescaling did NOT change. A random line going through the origin is fitted, the original data points are projected onto this line and the distances from the origin to these projected points are calculated. The sum of squared distances (to avoid negative values cancelling out positive ones) is calculated as (SS(distances)): \[ \begin{aligned} SS(distances) = d_{1}^2 + d_{2}^2 + ... + d_{n}^2 \end{aligned} \] with n = sample size

The line is rotated around the origin and the line with the maximum SS(distances) becomes PC1. This lines’ slope can be used to calculate singular vectors or Eigenvectors by looking at how many units the line goes along the x-axis in positive direction (b) if moved 1 unit in positive direction of the y-axis (c). Using pythagorean theorem the distance a (value along the slope) is equal to:
\[ \begin{aligned} a = \sqrt{b^2+c^2} \end{aligned} \] which can be easily calculated.

  • example: The slope is 0.25, then b=4 for c=1, using pythagorean theorem:

\[ \begin{aligned} a = \sqrt{b^2+c^2} = \sqrt{4^2+1^2} = \sqrt{16+1} = 4.12 \end{aligned} \] a, b and c are then scaled by factor a, which in turn leads to a being 1:

\[ \begin{aligned} a(scaled) & = \frac{a}{a} = 1\\ b(scaled) & = \frac{b}{a} = 0.97\\ c(scaled) & = \frac{c}{a} = 0.242\\ \end{aligned} \] This 1 unit long vector consisting of b(scaled) in the x-direction and c(scaled) in the y-direction is the Eigenvector consisting of 0.97 units var1 and 0.242 units var2. The Factors b(scaled) and c(scaled) are called loading scores and correspond to the importance of a particular variable to a principal component. In this example the loading scores tell us, in terms of how the values are projected onto PC1, var1 is 4 (0.97/0.242) times more important than var2.

In the case of only 2 variables PC2 is simply the line that is perpendicular to PC1. Then, the samples are also projected onto the PC2 axis. These projections of data on PC1 and PC2 on the PC1 and PC2 axis are then rotated so PC1 is horizontal. Afterwards out of these projections new positions for the samples are generated in the PC1 vs PC2 space.

The more dimensions the more complex this process gets, the PCs however are always perpendicular to each other and are uncorrelated. The issue of growing complexity when considering more than three dimensions can be solved mathematically as another word for SS(distances) is Eigenvalues, which can be computed by matrix algebra. Out of these Eigenvalues, the Eigenvectors can be constructed and eventually the PC lines can be generated even for high-dimensional data.

The variance of the PCs is simply the Eigenvalues or SS(distances) divided by the sample size minus one (n-1): \[ \begin{aligned} var(PC_{i}) &= \frac{SS(distances(PC_{i}))}{n-1}\\ \end{aligned} \] These variances can be used to calculate the proportion of variance in the data explained by each PC (variance explained) using the sum of variances : \[ \begin{aligned} Sum(variances) = \sum_{i = 1}^n var(PC_{i}) \end{aligned} \] To get the variance explained for each PC, the variance of the respective PC is divided by the sum of variances of all PCs.

  • Example to calculate variance explained for PC1 if var(PC1) is 15 and var(PC2) is 3:

\[ \begin{aligned} \frac{var(PC_{1})}{\sum_{i = 1}^n var(PC_{i})} = \frac{var(PC_{1})}{var(PC_{1})+var(PC_{2})} = \frac{15}{15+3} = 0.8\bar3 = 83.\bar3 \ \% \end{aligned} \]

In this example PC1 would explain 83.3 % of the variance in the data and PC2 would explain 16.7 % of the variance in the data. In R the prcomp function generates 3 parameters: x, sdev and rotation

  • x contains the PCs to draw a graph
  • sdev is the standard deviation of the PCs and can be transferred to the variance by squaring sdev and subsequently be used to calculate the variance explained
  • rotation corresponds to the loading scores which show the importance of variables in respect to each PC

1.2.2 Analysis

Afterwards, data was analyzed for general changes between cell lines. As explorative analysis,PCA was chosen as it breaks down multidimensional data and facilitates visualization of the underlying data structure.

# transform data for the format required by "PCA"
dat_PCA <- dat %>% 
  select(-c(expression)) %>%
  spread(miRNA, log_exp) %>%
  mutate(cell_line = str_replace_all(cell_line, "_","-"))

# scale data and perform PCA
res.pca <- PCA(dat_PCA[, -c(1:3)],  scale.unit = T, ncp = 5, graph = F)

# extract results and chose which PCs to use
eig.val <- get_eigenvalue(res.pca)

head(eig.val)

As shown above, when using three dimensions, the analysis is able to explain more than 70 % of the variance in the data. As we add more dimensions the explanation improves, naturally, however for visualization reasons and the complexity of imagining more than three dimensions, only the comparison of PC1 vs PC2, PC1 vs PC3 and PC2 vs PC3 are shown (Fig. 2).

fviz_pca_ind(
  res.pca,
  # Fill individuals by groups
  geom.ind = "point",
  fill.ind = dat_PCA$cell_line,
  col.ind = "black",
  pointshape = 21, 
  pointsize = dat_PCA$Irradiation,
  palette = "jco",
  addEllipses = T,
  axes = c(1, 2),
  # Variables
  alpha.var =0.5,
  mean.point = F,
  ellipse.level=0.8,
  legend.title = list(fill = "Cell line")
) + 
  scale_size_manual(values = c(2,4))
Fig. 2: PCA of the irradiated cell lines Met-1, Met-4, SCC-12, SCC-13, SCL-II. Large circles show irradiated samples, small circles indicate control samples. Dim1 is equivalent to Principal Component 1 (PC1), etc. Ellipses are drawn around the respective cell lines for illustration. The variance explained is shown in parentheses. NOTE: The code above only shows the plot for PC1 vs PC2 (axes = c(1,2)). The image was generated by saving the 3 different images (A: PC1 vs PC2,B: PC1 vs PC3,C: PC2 vs PC3) and combining them in power point. n = 4.

Fig. 2: PCA of the irradiated cell lines Met-1, Met-4, SCC-12, SCC-13, SCL-II. Large circles show irradiated samples, small circles indicate control samples. Dim1 is equivalent to Principal Component 1 (PC1), etc. Ellipses are drawn around the respective cell lines for illustration. The variance explained is shown in parentheses. NOTE: The code above only shows the plot for PC1 vs PC2 (axes = c(1,2)). The image was generated by saving the 3 different images (A: PC1 vs PC2,B: PC1 vs PC3,C: PC2 vs PC3) and combining them in power point. n = 4.

A separation of SCC-12/SCC-13 and Met-1/Met-4 is evident along the PC1 axis, PC2 separates SCL-II from all other cell lines. Within clusters (ellipses) irradiated cells (big circles) form subclusters in the PC1 vs PC2 plot as well as in the PC2 vs PC3 plot in all cell lines and in the PC1 vs PC3 plot in Met-4, SCC-13, and SCL-II. However the irradiation effects are not as pronounced as the cell line effects indicating a larger difference in the miRNA expression between cell lines than between treated and control cells.

To further investigate the indicated irradiation effect a second PCA plot has been drawn with an emphasis on treatment rather than cell line (Fig. 3).

fviz_pca_biplot(
  res.pca,
  # Fill individuals by groups
  geom.ind = "point",
  pointshape = 21,
  pointsize = 2.5,
  fill.ind = dat_PCA$Irradiation,
  col.ind = "black",
  palette = "jco",
  # Color variable by groups
  col.var = "cos2",
  alpha.var = 0.3,
  axes = c(1,2),
  addEllipses = T,
  ellipse.level=0.8,
  legend.title = list(fill = "Irradiation", color = "quality of representation"),
  repel = TRUE        # Avoid label overplotting
)+ 
  scale_size_manual(values = c(2,4))
Fig. 3: PCA of the irradiated cell lines Met-1, Met-4, SCC-12, SCC-13, SCL-II. Large circles represent the mean. Dim1 is equivalent to Principal Component 1 (PC1), etc. Ellipses are drawn around the treatment conditions. Arrows indicate correlation of miRNA with the respective Principal Component. miRNAs sharing a similar angle in the plot are positively correlated, miRNAs with orthogonal arrows are uncorrelated and miRNAs with an angle of 180° are negatively correlated. The variance explained is shown in parentheses. NOTE: The code above only shows the plot for PC1 vs PC2 (axes = c(1,2)). The image was generated by saving the 3 different images (A: PC1 vs PC2,B: PC1 vs PC3,C: PC2 vs PC3) and combining them in power point. n = 4.

Fig. 3: PCA of the irradiated cell lines Met-1, Met-4, SCC-12, SCC-13, SCL-II. Large circles represent the mean. Dim1 is equivalent to Principal Component 1 (PC1), etc. Ellipses are drawn around the treatment conditions. Arrows indicate correlation of miRNA with the respective Principal Component. miRNAs sharing a similar angle in the plot are positively correlated, miRNAs with orthogonal arrows are uncorrelated and miRNAs with an angle of 180° are negatively correlated. The variance explained is shown in parentheses. NOTE: The code above only shows the plot for PC1 vs PC2 (axes = c(1,2)). The image was generated by saving the 3 different images (A: PC1 vs PC2,B: PC1 vs PC3,C: PC2 vs PC3) and combining them in power point. n = 4.

Fig. 3 shows a putative irradiation effect correlating with PC2 and PC3.Although the majority of variance in the data originates from cell line differences as indicated in Fig. 2, a smaller but still substantial portion of the variance, indeed, stems from the irradiation treatment. These two effects - cell line effect and irradiation effect - were further analyzed.

1.3 Investigation of the cell line effect

To get a better understanding of the cell line effect a clustering analysis on differentially expressed miRNAs in control cells was performed.The statistical analysis underlying the characterization as differentially expressed is shown as follows:

1.3.1 Checking assumptions for statistical tests

# check for outliers 
outl <- dat %>% 
  group_by(cell_line,Irradiation, miRNA) %>%
  identify_outliers(log_exp) 
any(outl$is.extreme)

No extreme outliers were present in the analysis. Testing for normality or homogeneity of variances was not indicated in this study as the sample size was too small (n = 4) to detect deviations from said assumptions. Therefore, a theoretical approach has been used to solve this problem:

  • As explained in section 1.1, expression data follows a log-normal distribution, thus log-transformed values were used for statistical analysis
  • To deal with possible heterogeneity of variances, ANOVA with heteroscedasticity corrected covariance matrices (White 1980, Long and Ervin 2000) and post-hoc pairwise t-test with unequal variances were employed (white.adjust = TRUE in ANOVA and pool.sd = TRUE in pairwise t-test)

1.3.2 Two-Way ANOVA

Excursion: ANOVA

Analysis

A two-way ANOVA was conducted at each level of the factor miRNA to determine the effects of cell line and irradiation on miRNA expression. Statistical significance was accepted for p < 0.05 after fdr-adjustment (Benjamini & Hochberg 1995) for two-way interactions and simple main effects. The results of the two-way ANOVA are shown exemplary below.

# 2-way ANOVA with miRNA as moderator variable
two_way_ANOVA <- dat %>%
  group_by(miRNA) %>%
  # perform ANOVA with hccm correction (white.adjust = TRUE)
  anova_test(log_exp ~ cell_line*Irradiation, white.adjust = T) %>%
  adjust_pvalue(method = "fdr") 
two_way_ANOVA

In 5 out of the 40 miRNAs there was an interaction effect present (miR-126-3p, miR-146a-5p, miR-30a-3p, miR-30b-5p, miR-7-5p). A cell line main effect was observed in 38 out of 40 miRNAs (each of the miRNAs showing an interaction effect also showed a sigfnifcant main effect). Only for miRNA let-7f-p and miR-30d-5p no cell line effect could be observed after adjusting for multiple testing.

# show interaction
two_way_interaction <- two_way_ANOVA %>%
  filter(Effect == "cell_line:Irradiation" & p.adj < 0.05) %>%
  pull(miRNA)
two_way_ANOVA %>% 
  filter(miRNA %in% two_way_interaction & Effect == "cell_line:Irradiation") 

# show main cell line effect
two_way_cell<- two_way_ANOVA %>%
  filter(Effect == "cell_line" & p.adj < 0.05) %>%
  pull(miRNA)
two_way_ANOVA %>% 
  filter(miRNA %in% two_way_cell & Effect == "cell_line") 

# no effect
two_way_ANOVA %>% 
  filter(!miRNA %in% two_way_cell & Effect == "cell_line")

1.3.3 One-Way ANOVA

To further investigate the cell line effect a one-way ANOVA was conducted with miRNA and Irradiation as grouping variables. To eliminate the Irradiation effect and only compare baseline miRNA expression between cell lines the results were filtered for control cells only, resulting in 36 differentially expressed miRNAs.

# 1-way ANOVA 
one_way_ANOVA <- dat %>%
  group_by(miRNA, Irradiation) %>%
  # perform ANOVA with hccm correction (white.adjust = TRUE)
  anova_test(log_exp ~ cell_line, white.adjust = TRUE) %>%
  adjust_pvalue(method = "fdr") %>% 
  filter(Irradiation == "control" & p.adj < 0.05) %>%
  select(-Irradiation)
one_way_ANOVA

NOTE: using the pooled variance from a 2-way ANOVA in the following 1-way ANOVA yields a higher statistical power but is more susceptible to violations from the homogeneity of variance assumptions. Analogously post-hoc tests with pooled variances (pool.sd = TRUE) are better in situations when the assumptions are met, at the cost of being less robust when assumptions not met.

1.3.4 Cluster analysis

1.3.4.1 Theoretical background

Hierarchical clustering

Hierarchical clustering is a method to group data based on similarity in data structure and is mostly associated with heatmaps and dendrograms for data presentation. For gene/miRNA expression analysis genes/miRNAs typically represent rows and different samples represent columns. To find genes/miRNA that are similarly expressed, distances between genes/miRNAs are measured e.g. using euclidean distance:

\[ \begin{aligned} d = \sqrt{\sum_{i=1}^n (gene1_{i}-gene2_{i})^2} \end{aligned} \]

With gene1i being the expression of gene1 in sample i and gene2i being the expression of gene2 in sample i. An example for 2 samples and 2 genes is shown below. Let gene expression of gene1 be 1.6 in sample1 and 0.5 in sample2 and expression of gene2 be -0.5 in sample1 and -1.9 in sample2:

\[ \begin{aligned} d & = \sqrt{\sum_{i=1}^n (gene1_{i}-gene2_{i})^2} \\ & = \sqrt{(gene1_{1} - gene2_{1})^2 + (gene1_{2} - gene2_{2})^2} \\ & = \sqrt{(1.6 - (-0.5))^2 + (0.5 - (-1.9))^2} \\ & = \sqrt{2.1^2 + 2.4^2} \\ & = 3.2 \end{aligned} \] Note: for 2 samples the euclidean distance between 2 genes/miRNAs is equal to the pythagorean theorem.

Other possible distance measures include:

  • pearson correlation (parametric)
  • spearman correlation (non-parametric)
  • kendall correlation (non-parametric)
  • manhattan distance (instead of summing up squared distances and taking the sqaure root, absolute values of difference are used)
  • canberra distance
  • binary distance
  • minkowski distance
  • maximum distance

In more complex designs, distances are calculated for each gene/miRNA pair and the pair with the smallest distance is merged into a cluster (cluster1). Subsequently distances are calculated again but with the previously generated cluster being treated as a new gene/miRNA entity. If the smallest distance is between 2 other genes/miRNas, they are merged into a new separate cluster, if the smallest distance is between some gene/miRNA and cluster1, this gene is clustered next to cluster1. This process is repeated until all genes/miRNas are part of a cluster. To visualize this process a dendrogram is drawn, showing different branches to indicate relationships. The length of the branches corresponds to the time when this cluster was formed, meaning the shorter the branches the closer the relationship between the genes/miRNAs.

There are different approaches to cluster similar samples together, the most prominent being, average linkage, single linkage and complete linkage. In average linkage the distance of single genes/miRNAs to the centroid of clusters is calculated and they are merged into the cluster with the least distance to the centroid. In single linkage the distance is calculated between genes/miRNAs and the closest point in each cluster. Analogously, in complete linkage, the distance is calculated between genes/miRNas and the furthest point in each cluster.

Finally, not only genes/miRNAs can be clustered but this process can also be applied to different samples to find related samples based on the expression pattern.

Note: The choice of distance measures and clustering algorithms is completely arbitrary, so the best method is chosen by looking at the representation of the data for each process. However, there are studies indicating that distances between genes/miRNAs can preferably be calculated by correlation whereas distances between samples typically are calculated using euclidean distance. (Publications raussuchen)


K-means clustering

K-means is a different approach to cluster similar data but with a different mathematical approach and the need of supervision of a researcher, whereas hierarchical clustering typically is an unsupervised method. In k-means clustering a number k of desired clusters is specified previously to the analysis (methods to find the best k are described in a later paragraph). For an example with k=3 clusters, three random data points are chosen as the center of a cluster. Afterwards distances from each point to the three randomly chosen centers are calculated and the points are assigned to the closest cluster. In the following, the mean for each cluster is calculated and the distance from each point to the mean of each cluster is calculated. If necessary, points are reassigned and this process is repeated until the samples in the cluster do not change anymore. This explanation refers to one iteration of the k-means algorithm. The number of iterations can also be prespecified, and for each iteration three new random points are chosen as the starting points for the clusters. For each iteration the sum of variances within the clusters is calculated and summarized over all clusters. The iteration with the least sum of variances is chosen as the optimal clustering result.

To find the optimal value of k, different approaches can be used. Sometimes it is evident from a plot, a previous PCA or hierarchical cluster analysis or other exploratory data analyses how many clusters are optimal. In other cases different values for k can be used in a trial and error approach and the reduction of variance can be plotted against k. In this elbow plot there is a point after which the reduction of variance only changes slightly. This point generally corresponds to the optimal k.

1.3.4.2 Analysis

The differentially expressed miRNAs were used in a combined approach using supervised kmeans to cluster cell lines (columns) with k=3 as indicated by PCA and unsupervised hierachical clustering to cluster miRNAs (rows). Furthermore hierarchical clustering was also applied in the subclusters split by kmeans. The results were visualized in a Heatmap to reduce complexity and show the quantitative properties of each miRNA as an overview (Fig. 4).

# Heatmap  
# transform data for Heatmap format
dat_Heatmap <- dat %>% 
  filter(Irradiation == "control" & miRNA %in% one_way_ANOVA$miRNA) %>%
  select(-c(Irradiation, log_exp)) %>%
  spread(miRNA, expression) %>%
  mutate(cell_line = str_replace_all(cell_line, "_","-"))

# scale data for Heatmap
dat_scaled <- dat_Heatmap %>% 
  column_to_rownames("ID") %>% 
  select(-cell_line) %>%
  scale() %>%
  t()

# set ID as rownames so colorbar works properly
dat_colorbar <- dat_Heatmap %>% select(c(ID, cell_line)) %>% 
  column_to_rownames("ID")

# define colors for colorbar to identify cell lines
colorbar <- HeatmapAnnotation(
  df =dat_colorbar,
  col = list(
    cell_line = c(
      "Met-1" = "#0073C2FF",
      "Met-4" = "#EFC000FF",
      "SCC-12"="#868686FF" ,
      "SCC-13"="#CD534CFF",
      "SCL-II"="#7AA6DCFF")
    ),
  annotation_legend_param = list(
    cell_line = list(nrow=1)
    )
  )

# define color for the Heatmap cells
col_fun = colorRamp2(c(-1.8, 0, 1.8), c(c("#6D9EC1", "white", "#E46726")))

# Draw Heatmap 
Ht <- Heatmap(
  dat_scaled,
  col= col_fun,
  top_annotation = colorbar,
  row_split = 4,
  column_title = c("A", "B", "C"),
  border = T,
  # split cell lines in 3 clusters according to PCA
  column_km = 3, 
  # repeat km split 100 times to get a stable cluster
  column_km_repeats = 100, 
  # define distance metric and clustering algorithm
  clustering_method_row = "average", # average linkage
  clustering_method_columns = "average",
  clustering_distance_row = "pearson", 
  clustering_distance_column = "euclidean",
  # plot cosmetics 
  rect_gp = gpar(col = "white",lty = 1, lwd = 1),
  row_names_gp = gpar(fontsize = 10),
  show_column_names = FALSE,
  column_names_gp = gpar(fontsize = 10),
  heatmap_legend_param = list(
    title = "row Z-score",
    at = seq(-2,2,by=1),
    color_bar="continuous",
    title_position ="topcenter",
    legend_direction = "horizontal",
    legend_width = unit(4, "cm")
    ))

# plot the final heatmap with annotation and legend
draw(Ht, annotation_legend_side = "bottom", heatmap_legend_side = "bottom")
Fig. 4: Hierarchical clustering analysis of differentially expressed miRNAs between the five different cell lines. K-means clustering was applied with k=3 splits as PCA indicated 3 distinct clusters (Met-1/Met-4, SCC-12/SCC-13 and SCL-II). These clusters are also present in the Heatmap displayed by the color code below the column dendrogram. Orange shows upregulation of miRNA expression, blue shows downregulation of miRNA expression. Clustering method: average linkage. Distance measure for miRNAs: pearson correlation. Distance measure for cell lines: euclidean distance. n = 4. )

Fig. 4: Hierarchical clustering analysis of differentially expressed miRNAs between the five different cell lines. K-means clustering was applied with k=3 splits as PCA indicated 3 distinct clusters (Met-1/Met-4, SCC-12/SCC-13 and SCL-II). These clusters are also present in the Heatmap displayed by the color code below the column dendrogram. Orange shows upregulation of miRNA expression, blue shows downregulation of miRNA expression. Clustering method: average linkage. Distance measure for miRNAs: pearson correlation. Distance measure for cell lines: euclidean distance. n = 4. )

The combined cluster analysis showed a clear separation of miRNA expression depending on the cell line context (A: SCC-12/SCC-13,B: SCL-II,C: Met-1/Met-4). The miRNAs were clustered in 4 groups. Cluster 1 was upregulated in cell line cluster A compared to cluster B and C. Cluster 2 was upregulated in cell line cluster B compared to cluster A and C. Cluster 4 was upregulated in cell line cluster C compared to A and B. Cluster 3 showed an intermediate expression of miRNAs in Cluster B and C with the lowest expression values observed in Cluster A.

Taken together these findings indicate distinct miRNA clusters representing a cell line specific epigenetic pattern and possibly reflecting differentiation, p53 status or other phenotypes associated with these patterns. To investigate the biological function of the miRNAs in each cluster gene set enrichment analysis was conducted to find enriched pathways targeted by these miRNAs (section 1.3.5).

1.3.5 Gene set enrichment analysis (GSEA) with RBiomirGS

To identify the summarized function of the differentially expressed miRNAs between cell lines, miRNA clusters obtained in 1.3.4.2 were further investigated. Three distinct clusters were selected - namely cluster 1A (representing miRNAs overexpressed in cell cluster 1 containing SCC12 and SCC13), cluster 2B (miRNAs overexpressed in cell line cluster 2 containing SCL-II) and cluster 4C (miRNAs overexpressed in cell line cluster 4 containg Met-1 and Met-4) - and data was extracted from the heatmap object:

# extract clusters out of Heatmap object
Ht_clusters <- extract_clusters(dat_scaled, Ht, sampleName = "ID", sampleClust = "cellCluster", 
                                geneName = "miRNA", geneClust = "miRCluster")

# construct new data frame containing cluster information
dat_clusters <- left_join(filter(dat, Irradiation == "control"), Ht_clusters$cellCluster) %>%
  left_join(Ht_clusters$miRCluster) %>% select(-c(Irradiation, cell_line)) %>%
  mutate(miRNA = str_replace_all(miRNA,"let", "hsa-let"),
         miRNA = str_replace_all(miRNA,"mir", "hsa-miR"))

Afterwards fold-changes and pvalues were calculated for upregulated miRNAs in each cell line cluster vs the remaining 2 (e.g. miRNAs in cluster 1A vs miRNAs in cluster 1B + 1C).

# create list for each miRCluster
ls_miRCluster <- split(dat_clusters, f = dat_clusters$miRCluster)         

# compare Cluster 1A to 1B and 1C, drop attributes (important for the pathway analysis as a list threw an error) and generate a data.frame
cl_1A <- as.data.frame(lapply(summary_clusters(ls_miRCluster, 1, "A"), FUN=drop_attr))
# compare Cluster2B to 2A and 2C, drop attributes and generate a data.frame
cl_2B <- as.data.frame(lapply(summary_clusters(ls_miRCluster, 2, "B"), FUN=drop_attr))
# compare Cluster 4C to 4A and 4B, drop attributes and generate a data.frame
cl_4C <- as.data.frame(lapply(summary_clusters(ls_miRCluster, 4, "C"), FUN=drop_attr))

These dataframes containing the miRNA name, the fold-change and pvalue of the specified cell line cluster vs the other two for each miRNA were then used for GSEA with the R package RBiomirGS providing a comprehensive tool for quantitative investigation of miRNA-mRNA interactions (Zhang 2018). Sources for gene sets used in this analyses were KEGG (Kyoto Encyclopedia of Genes and Genomes) and GO:BP (Gene Ontology: Biological Process) obtained from http://www.gsea-msigdb.org/gsea/msigdb/index.jsp as entrez IDs stored in .gmt files. The metric for the GSEA in this package is logistic regression with a negative model coefficient related to gene sets inhibited by the miRNA set under investigation and a positive model coefficient associated with gene sets activated by the miRNA set.

Bioinformatic approaches are prone to false-positive results (Godard 2015) due to annotation and research bias concerning miRNAs and pathways: On the one hand certain miRNAs are researched more extensively leading to a higher number of identified targets, on the other hand there are certain pathways - mostly associated with cancer - which are highly related and therefore enriched in many studies even though different approaches were used in those studies. Thus, the need for negative controls is crucial to eliminate this bias.

In this study three clusters should be examined with a total of 30 miRNAs (cluster 1A: 10 miRNAs, cluster 2B: 6 miRNAs, cluster 4C: 14 miRNAs) resulting in an average number of 10 miRNAs in each cluster. Therefore 10 random mature miRNAs were chosen out of a total of 2635 miRNAs obtained from miRBase (www.mirbase.org) as controls. These miRNAs were assigned random FC and pvalue pairs out of the original analysis as this is required for the performed quantitative analysis. This process was repeated 50 times to ensure a sufficiently large number of control miRNA sets. As this iterative process is time consuming, once the control data was generated it was stored in an .rds object to be accessed later. To assess bias, the number of times a pathway was enriched in these 50 control simulations was stored and divided by 50 to obtain an enrichment percentage. Pathways that were enriched in more than 10 % of controls were then omitted from the analysis to reduce bias.

1.3.5.1 KEGG pathway analysis

Calculation of controls for KEGG analysis:

# load data with mature miRNAs from miRBase
dat_miRBase <- read.csv("Data/Pathway Analysis/mature_miRNA.csv", header = FALSE) %>%
  mutate(miRNA = str_extract(V1, "(hsa-miR|hsa-let)-\\d{1,5}([:alpha:]+-\\dp|\\s|-\\dp|[:alpha:]+)")) %>% 
  na.omit()

# data frame containing FC and pvalue of the original data used for random sampling in controls
ctrl_stats <- rbind(cl_1A, cl_2B, cl_4C) %>% 
  select(-miRNA) 

# calculate GS enrichment for 50 random controls (containing 10 miRNAs each)
n <- 50
# ctrl_list_KEGG <- GS_controls(data= ctrl_stats,rep = n, miRdata = dat_miRBase$miRNA, sample_n = 10,
#                          gs_file = "c2.cp.kegg.v7.2.entrez.gmt")

# to facilitate downstream analysis the ctrl_list is saved 
# saveRDS(ctrl_list, file = "ctrl_list.rds")
ctrl_list_KEGG <- readRDS(file = "Data/Pathway Analysis/ctrl_list_KEGG.rds") # file is available at https://github.com/MBender1992/PhD/blob/Marc/Data/Pathway%20Analysis/ctrl_list_KEGG.rds

# calculate bias and mean targeted genes
res_ctrl_KEGG <- pathway_ctrl_summary(ctrl_list_KEGG, n=n)



Cluster 1A

Comparison of miRNAs upregulcl_1A_predicted_mirna_mrna_iwls_KEGGated in SCC-12/SCC-13 vs SCL-II, Met-1 and Met-4.

# calculation of GSEA for miRNAs upregulated in cluster 1A 

# collect mRNA targets of the miRNAs upregulated in cluster 1A
rbiomirgs_mrnascan_custom(objTitle = "cl_1A_predicted", mir = cl_1A$miRNA, sp = "hsa", 
  queryType = "predicted",parallelComputing = TRUE,clusterType = "PSOCK")

# calculate GS by logistic regression
rbiomirgs_logistic(objTitle = "cl_1A_predicted_mirna_mrna_iwls_KEGG",mirna_DE = cl_1A, 
  var_mirnaName = "miRNA",var_mirnaFC = "FC",var_mirnaP = "pvalue", mrnalist = cl_1A_predicted_mrna_entrez_list, 
  mrna_Weight = NULL, gs_file = "Data/Pathway Analysis/c2.cp.kegg.v7.2.entrez.gmt", optim_method = "IWLS", 
  p.adj = "fdr", parallelComputing = FALSE, clusterType = "PSOCK")

# total number of significantly enriched pathways
sum(cl_1A_predicted_mirna_mrna_iwls_KEGG_GS$adj.p.val < 0.05)

# remove enriched pathways with a random enrichment of more than 10 %
bias_KEGG <- names(res_ctrl_KEGG$bias[res_ctrl_KEGG$bias > 0.1])
cl_1A_KEGG_plot <- cl_1A_predicted_mirna_mrna_iwls_KEGG_GS %>% filter(!GS %in% bias_KEGG)

In total 13 (12 after bias correction) KEGG pathways were significantly enriched in the gene set targeted by the 10 miRNAs in cluster 1A. One pathway (KEGG_Glioma) was excluded from the downstream analysis as it was enriched in more than 10 % of control simulations (also for the analysis in cluster 2B and cluster 4C).

#plot results (volcano plot)
rbiomirgs_volcano(gsadfm = cl_1A_KEGG_plot,topgsLabel = TRUE,n = 15,gsLabelSize = 2,
  sigColour = "red",plotWidth = 250,plotHeight = 220,xLabel = "model coefficient")
# plot distribution of enriched gene sets
rbiomirgs_bar(gsadfm = cl_1A_KEGG_plot,signif_only = F,gs.name = F,
  n = "all",xLabel = "gene set", yLabel = "model coefficient", plotWidth = 250, plotHeight = 220)
# plot top enriched gene sets
rbiomirgs_bar(gsadfm = cl_1A_KEGG_plot,signif_only = 15,gs.name = T,xLabel = "model coefficient",
              yTxtSize = 7, n = 15, plotWidth = 250, plotHeight = 220)
Fig. 5: KEGG pathway analysis of gene sets targeted by miRNAs in cluster 1A. Volcano plot depicts the significance and directionality distribution for the KEGG pathway tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched KEGG pathways and the bar graph in the volcano plot shows the overall distribution of model coefficient. The 12 significantly enriched pathways are labeled. Bar graph on the left shows these 12 enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted

Fig. 5: KEGG pathway analysis of gene sets targeted by miRNAs in cluster 1A. Volcano plot depicts the significance and directionality distribution for the KEGG pathway tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched KEGG pathways and the bar graph in the volcano plot shows the overall distribution of model coefficient. The 12 significantly enriched pathways are labeled. Bar graph on the left shows these 12 enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted

Interpretation???



Cluster 2B

Comparison of miRNAs upregulated in SCL-II vs. SCC-12, SCC-13 Met-1 and Met-4.

# collect mRNA targets of the miRNAs upregulated in cluster 2B
rbiomirgs_mrnascan_custom(objTitle = "cl_2B_predicted", mir = cl_2B$miRNA, sp = "hsa", 
                   queryType = "predicted",parallelComputing = TRUE,clusterType = "PSOCK")

# calculate GS by logistic regression
rbiomirgs_logistic(objTitle = "cl_2B_predicted_mirna_mrna_iwls_KEGG",mirna_DE = cl_2B, 
                   var_mirnaName = "miRNA",var_mirnaFC = "FC",var_mirnaP = "pvalue", mrnalist = cl_2B_predicted_mrna_entrez_list, 
                   mrna_Weight = NULL, gs_file = "Data/Pathway Analysis/c2.cp.kegg.v7.2.entrez.gmt", optim_method = "IWLS", 
                   p.adj = "fdr", parallelComputing = FALSE, clusterType = "PSOCK")

# total number of significantly enriched pathways
sum(cl_2B_predicted_mirna_mrna_iwls_KEGG_GS$adj.p.val < 0.05)

# remove enriched pathways with a random enrichment of more than 10 %
cl_2B_KEGG_plot <- cl_2B_predicted_mirna_mrna_iwls_KEGG_GS %>% filter(!GS %in% bias_KEGG)

In total 34 (33 after bias correction) KEGG pathways were significantly enriched in cluster 2B.

#plot results (volcano plot)
rbiomirgs_volcano(gsadfm = cl_2B_KEGG_plot,topgsLabel = TRUE,n = 15,gsLabelSize = 2,
                  sigColour = "red",plotWidth = 250,plotHeight = 220,xLabel = "model coefficient")

# plot distribution of enriched gene sets
rbiomirgs_bar(gsadfm = cl_2B_KEGG_plot,signif_only = F,gs.name = F,
              n = "all",xLabel = "gene set", yLabel = "model coefficient", plotWidth = 250, plotHeight = 220)

# plot top enriched gene sets
rbiomirgs_bar(gsadfm = cl_2B_KEGG_plot,signif_only = T,gs.name = T,xLabel = "model coefficient",
              yTxtSize = 7, n = "all", plotWidth = 250, plotHeight = 220)
Fig. 6: KEGG pathway analysis of gene sets targeted by miRNAs in cluster 2B. Volcano plot depicts the significance and directionality distribution for the KEGG pathway tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched KEGG pathways and the bar graph in the volcano plot shows the overall distribution of model coefficient. The top 15 significantly enriched pathways are labeled. Bar graph on the left shows all 33 significntly enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted

Fig. 6: KEGG pathway analysis of gene sets targeted by miRNAs in cluster 2B. Volcano plot depicts the significance and directionality distribution for the KEGG pathway tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched KEGG pathways and the bar graph in the volcano plot shows the overall distribution of model coefficient. The top 15 significantly enriched pathways are labeled. Bar graph on the left shows all 33 significntly enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted

Interpretation???



Cluster 4C

Comparison of miRNAs upregulated in Met-1 and Met-4 vs. SCC-12, SCC-13 and SCL-II.

# collect mRNA targets of the miRNAs upregulated in cluster 4C
rbiomirgs_mrnascan_custom(objTitle = "cl_4C_predicted", mir = cl_4C$miRNA, sp = "hsa", 
                   queryType = "predicted",parallelComputing = TRUE,clusterType = "PSOCK")

# calculate GS by logistic regression
rbiomirgs_logistic(objTitle = "cl_4C_predicted_mirna_mrna_iwls_KEGG",mirna_DE = cl_4C, 
                   var_mirnaName = "miRNA",var_mirnaFC = "FC",var_mirnaP = "pvalue", mrnalist = cl_4C_predicted_mrna_entrez_list, 
                   mrna_Weight = NULL, gs_file = "Data/Pathway Analysis/c2.cp.kegg.v7.2.entrez.gmt", optim_method = "IWLS", 
                   p.adj = "fdr", parallelComputing = FALSE, clusterType = "PSOCK")

# total number of significantly enriched pathways
sum(cl_4C_predicted_mirna_mrna_iwls_KEGG_GS$adj.p.val < 0.05)

# remove enriched pathways with a random enrichment of more than 10 %
cl_4C_KEGG_plot <- cl_4C_predicted_mirna_mrna_iwls_KEGG_GS %>% filter(!GS %in% bias_KEGG)

In total 32 (31 after bias correction) KEGG pathways were significantly enriched in cluster 4C.

#plot results (volcano plot)
rbiomirgs_volcano(gsadfm = cl_4C_KEGG_plot,topgsLabel = TRUE,n = 15,gsLabelSize = 2,
                  sigColour = "red",plotWidth = 250,plotHeight = 220,xLabel = "model coefficient")

# plot distribution of enriched gene sets
rbiomirgs_bar(gsadfm = cl_4C_KEGG_plot,signif_only = F,gs.name = F,
              n = "all",xLabel = "gene set", yLabel = "model coefficient", plotWidth = 250, plotHeight = 220)

# plot top enriched gene sets
rbiomirgs_bar(gsadfm = cl_4C_KEGG_plot,signif_only = 15,gs.name = T,xLabel = "model coefficient",
              yTxtSize = 7, n = "all", plotWidth = 250, plotHeight = 220)
Fig. 7: KEGG pathway analysis of gene sets targeted by miRNAs in cluster 4C. Volcano plot depicts the significance and directionality distribution for the KEGG pathway tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched KEGG pathways and the bar graph in the volcano plot shows the overall distribution of model coefficient. The top 15 significantly enriched pathways are labeled. Bar graph on the left shows all 31 significntly enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted

Fig. 7: KEGG pathway analysis of gene sets targeted by miRNAs in cluster 4C. Volcano plot depicts the significance and directionality distribution for the KEGG pathway tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched KEGG pathways and the bar graph in the volcano plot shows the overall distribution of model coefficient. The top 15 significantly enriched pathways are labeled. Bar graph on the left shows all 31 significntly enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted

Interpretation???



1.3.5.2 GO:BP analysis

Calculation of controls for GO:BP analysis:

# calculate GS enrichment for 50 random controls 
n <- 50
# ctrl_list_GO_BP <- GS_controls(data= ctrl_stats,rep = n, miRdata = dat_miRBase$miRNA, sample_n = 10, 
#                          gs_file = "c5.go.bp.v7.2.entrez.xls")

# to facilitate downstream analysis the ctrl_list is saved 
# saveRDS(ctrl_list_GO_BP, file = "ctrl_list_GO_BP.rds")
ctrl_list_GO_BP<- readRDS(file = "Data/Pathway Analysis/ctrl_list_GO_BP.rds") # file is available at https://github.com/MBender1992/PhD/blob/Marc/Data/Pathway%20Analysis/ctrl_list_GO_BP.rds

# calculate bias and mean targeted genes
res_ctrl_GO_BP <-pathway_ctrl_summary(ctrl_list_GO_BP, n=n)



Cluster 1A

# calculate GS by logistic regression
rbiomirgs_logistic(objTitle = "cl_1A_predicted_mirna_mrna_iwls_GO_BP",mirna_DE = cl_1A, 
  var_mirnaName = "miRNA",var_mirnaFC = "FC",var_mirnaP = "pvalue", mrnalist = cl_1A_predicted_mrna_entrez_list, 
  mrna_Weight = NULL,gs_file = "Data/Pathway Analysis/c5.go.bp.v7.2.entrez.xls",optim_method = "IWLS", 
  p.adj = "fdr",parallelComputing = FALSE,clusterType = "PSOCK")

# number of enriched GO terms
sum(cl_1A_predicted_mirna_mrna_iwls_GO_BP_GS$adj.p.val < 0.05)

# remove enriched pathways with a random enrichment of more than 10 % and only keep pathways that converged
bias_GO_BP <- names(res_ctrl_GO_BP$bias[res_ctrl_GO_BP$bias > 0.1])
cl_1A_Go_BP_plot <- cl_1A_predicted_mirna_mrna_iwls_GO_BP_GS %>% filter(!GS %in% bias_GO_BP & converged == "Y")# number of significantly enriched pathways

In total 501 (442 after bias correction) GO terms (biological process) were significantly enriched. 59 Go terms were randomly enriched in more than 10 % of control simulations and omitted from the analysis (also for cluster 2B and 4C).

#plot results (volcano plot)
rbiomirgs_volcano(gsadfm = cl_1A_GO_BP_plot,topgsLabel = TRUE,n = 5,gsLabelSize = 1.8,
                  sigColour = "#CD534CFF",plotWidth = 250,plotHeight = 220,xLabel = "model coefficient")

# plot distribution of enriched gene sets
rbiomirgs_bar(gsadfm = cl_1A_GO_BP_plot,signif_only = F,gs.name = F,
              n = "all",xLabel = "gene set", yLabel = "model coefficient", plotWidth = 250, plotHeight = 220)

# plot top enriched gene sets
rbiomirgs_bar(gsadfm = cl_1A_GO_BP_plot,signif_only = 15,gs.name = T,xLabel = "model coefficient",
              yTxtSize = 7, n = 50, plotWidth = 250, plotHeight = 220)
Fig. 8: GO:BP analysis of gene sets targeted by miRNAs in cluster 1A. Volcano plot depicts the significance and directionality distribution for the GO terms tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched GO terms and the bar graph in the volcano plot shows the overall distribution of model coefficient. The top 5 significantly enriched pathways are labeled. Bar graph on the left shows the top 50 enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted

Fig. 8: GO:BP analysis of gene sets targeted by miRNAs in cluster 1A. Volcano plot depicts the significance and directionality distribution for the GO terms tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched GO terms and the bar graph in the volcano plot shows the overall distribution of model coefficient. The top 5 significantly enriched pathways are labeled. Bar graph on the left shows the top 50 enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted



Cluster 2B

# calculate GS by logistic regression
rbiomirgs_logistic(objTitle = "cl_2B_predicted_mirna_mrna_iwls_GO_BP",mirna_DE = cl_2B, 
                   var_mirnaName = "miRNA",var_mirnaFC = "FC",var_mirnaP = "pvalue", mrnalist = cl_2B_predicted_mrna_entrez_list, 
                   mrna_Weight = NULL,gs_file = "Data/Pathway Analysis/c5.go.bp.v7.2.entrez.xls",optim_method = "IWLS", 
                   p.adj = "fdr",parallelComputing = FALSE,clusterType = "PSOCK")

# number of enriched GO terms
sum(cl_2B_predicted_mirna_mrna_iwls_GO_BP_GS$adj.p.val < 0.05)

# remove enriched pathways with a random enrichment of more than 10 % and only keep pathways that converged
cl_2B_Go_BP_plot <- cl_2B_predicted_mirna_mrna_iwls_GO_BP_GS %>% filter(!GS %in% bias_GO_BP & converged == "Y")# number of significantly enriched pathways

In total 525 (466 after bias correction) GO terms were enriched in cluster 2B.

#plot results (volcano plot)
rbiomirgs_volcano(gsadfm = cl_2B_GO_BP_plot,topgsLabel = TRUE,n = 10,gsLabelSize = 1.8,
                  sigColour = "#CD534CFF",plotWidth = 250,plotHeight = 220,xLabel = "model coefficient")

# plot distribution of enriched gene sets
rbiomirgs_bar(gsadfm = cl_2B_GO_BP_plot,signif_only = F,gs.name = F,
              n = "all",xLabel = "gene set", yLabel = "model coefficient", plotWidth = 250, plotHeight = 220)

# plot top enriched gene sets
rbiomirgs_bar(gsadfm = cl_2B_GO_BP_plot,signif_only = T,gs.name = T,xLabel = "model coefficient",
              yTxtSize = 7, n = 50, plotWidth = 250, plotHeight = 220)
Fig. 9: GO:BP analysis of gene sets targeted by miRNAs in cluster 2B. Volcano plot depicts the significance and directionality distribution for the GO terms tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched GO terms and the bar graph in the volcano plot shows the overall distribution of model coefficient. The top 10 significantly enriched pathways are labeled. Bar graph on the left shows the top 50 enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted.

Fig. 9: GO:BP analysis of gene sets targeted by miRNAs in cluster 2B. Volcano plot depicts the significance and directionality distribution for the GO terms tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched GO terms and the bar graph in the volcano plot shows the overall distribution of model coefficient. The top 10 significantly enriched pathways are labeled. Bar graph on the left shows the top 50 enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted.



Cluster 4C

# calculate GS by logistic regression
rbiomirgs_logistic(objTitle = "cl_4C_predicted_mirna_mrna_iwls_GO_BP",mirna_DE = cl_4C, 
                   var_mirnaName = "miRNA",var_mirnaFC = "FC",var_mirnaP = "pvalue", mrnalist = cl_4C_predicted_mrna_entrez_list, 
                   mrna_Weight = NULL,gs_file = "Data/Pathway Analysis/c5.go.bp.v7.2.entrez.xls",optim_method = "IWLS", 
                   p.adj = "fdr",parallelComputing = FALSE,clusterType = "PSOCK")

# number of enriched GO terms
sum(cl_4C_predicted_mirna_mrna_iwls_GO_BP_GS$adj.p.val < 0.05)

# remove enriched pathways with a random enrichment of more than 10 % and only keep pathways that converged
cl_4C_Go_BP_plot <- cl_4C_predicted_mirna_mrna_iwls_GO_BP_GS %>% filter(!GS %in% bias_GO_BP & converged == "Y")# number of significantly enriched pathways

In total 766 (707 after bias correction) GO terms were enriched in cluster 4C.

#plot results (volcano plot)
rbiomirgs_volcano(gsadfm = cl_4C_GO_BP_plot,topgsLabel = TRUE,n = 10,gsLabelSize = 1.8,
                  sigColour = "#CD534CFF",plotWidth = 250,plotHeight = 220,xLabel = "model coefficient")

# plot distribution of enriched gene sets
rbiomirgs_bar(gsadfm = cl_4C_GO_BP_plot,signif_only = F,gs.name = F,
              n = "all",xLabel = "gene set", yLabel = "model coefficient", plotWidth = 250, plotHeight = 220)

# plot top enriched gene sets
rbiomirgs_bar(gsadfm = cl_4C_GO_BP_plot,signif_only = T,gs.name = T,xLabel = "model coefficient",
              yTxtSize = 7, n = 50, plotWidth = 250, plotHeight = 220)
Fig. 10: GO:BP analysis of gene sets targeted by miRNAs in cluster 4C. Volcano plot depicts the significance and directionality distribution for the GO terms tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched GO terms and the bar graph in the volcano plot shows the overall distribution of model coefficient. The top 10 significantly enriched pathways are labeled. Bar graph on the left shows the top 50 enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted.

Fig. 10: GO:BP analysis of gene sets targeted by miRNAs in cluster 4C. Volcano plot depicts the significance and directionality distribution for the GO terms tested (−log p value vs. model coefficient). Red (upper quadrants) represent the significantly enriched GO terms and the bar graph in the volcano plot shows the overall distribution of model coefficient. The top 10 significantly enriched pathways are labeled. Bar graph on the left shows the top 50 enriched gene sets in a quantitative representation. The bars represent model coefficient ± standard error. Only the gene sets with an FDR adjusted p < 0.05 are plotted.



1.4 Investigation of the irradiation effect

To examine the effect of the chronic Irradiation and identify in which cell lines there was an irradiation effect, pairwise comparisons between treated and control samples were conducted for each cell line using t-tests. To balance Type I and Type II error rate the results were only adjusted for multiple testing at the ANOVA (section 1.3.2) level using fdr-correction. Subsequent t-test were not adjusted for multiple testing as suggested by Feise (2002) and Rothman (1990). Confirmation of the results was rather achieved by a follow-up qPCR (Fig. 7).

Differential expression was accepted when fdr(ANOVA) < 0.05, p(t-test) < 0.05 and a fold-change > 1.5 between irradiated cells and controls was observed. Analysis of miRNAs was split into two parts: examination of the interaction effect and the irradiation main effect.

1.4.1 Interaction effect of cell line and irradiation

As mentioned above 5 miRNAs showed a significant interaction effect in the two-way ANOVA (section 1.3.2):

# miRNAs with a significant interaction effect
two_way_ANOVA %>% 
  filter(miRNA %in% two_way_interaction & Effect == "cell_line:Irradiation") 

Data was summarized using geometric mean and geometric sd to show data in the original scale but summarized with respect to the log-normal distribution of the miRNA expression values. Fold changes were calculated by dividing the geometric mean of the irradiated samples by the geometric mean of the control cells for each miRNA and cell line, respectively. For easier computation and giving similar weight to downregulation as to upregulation, fold changes were log2 transformed (log2FC).The analogous threshold to FC > 1.5 is |log2FC| > 0.585.

# summarize data with geometric mean and geometric sd for each miRNA in each cell line for irradiated cells and controls
dat_summary <- dat %>% 
  mutate(expression = expression + 1) %>%
  group_by(cell_line, Irradiation,miRNA) %>%
  summarize(geomean = geoMean(expression, na.rm =T), geosd = geoSD(expression))
# calculate fold changes by dividing the geomean expression value of irradiated cells by geomean expression value of 
# control cells for each each miRNA in each cell line
folds <-  dat_summary %>% 
  group_by(cell_line,  miRNA) %>% 
  summarize(FC = geomean[Irradiation == "KAUVIR"]/geomean[Irradiation == "control"]) %>% 
  mutate(log2FC = log2(FC)) %>%
  setNames(c("cell_line", "miRNA","FC", "log2FC"))

Combining the criterea for different expression as described in section 1.4, four miRNAs remained (Fig. 11).

# t-test for the interaction effect
pwc_interaction <- dat %>%
  group_by(miRNA,cell_line) %>%
# set pool.sd = F to use different variances for calculations
  pairwise_t_test(log_exp~Irradiation, pool.sd = F) %>%
#filter only miRNAs with p < 0.05 and a significant interaction term in two way ANOVA
  filter(p < 0.05 & miRNA %in% two_way_interaction)  


#calculate differential expression for interaction
diff_expr_interaction <- pwc_interaction %>%
  inner_join(folds) %>%
  select(miRNA, cell_line, p, log2FC) %>% 
  filter(abs(log2FC) > log2(1.5))
diff_expr_interaction
# function expands facet limits individually to plot each facet with an individual scale
facet_limits <-function(data, y, group){
  
  dat <- data.table(data)
  
  dat[,y_min := eval(parse(text = y))*0.5, by = eval(parse(text = group))]
  dat[,y_max:= eval(parse(text = y))*1.25, by = eval(parse(text = group))]
  
  dat <- as_tibble(dat)
  return(dat)
}

# apply function facet_limits to generate individual facet limits for the plot
dat_plot <- facet_limits(dat_summary, "geomean + geosd", "miRNA") %>% 
  mutate(cell_line = str_replace_all(cell_line, "_","-"))

# define limits of errorbar to only show upper errorbar
limits <- aes(ymax = ifelse(geomean>0,geomean + geosd,geomean/2),
              ymin = ifelse(geomean<0,geomean - geosd,geomean/2))


# generating Plot
dat_plot %>% 
  # only show differentially expressed miRNAs with a significant interaction term in two-way ANOVA
  filter(miRNA %in% diff_expr_interaction$miRNA) %>%
  ggplot(
    aes(
      x=cell_line,
      y=geomean,
      fill=Irradiation
      )
    ) + 
  # add errorbars with the defined limits
  geom_errorbar(
    limits,
    width=.2,
    position=position_dodge(0.5)
    ) +
  # add barplots to show geometric mean
  geom_bar(
    stat="identity",
    color="black",
    position=position_dodge(),
    width= 0.5
    ) +
  # split plot into separate plot for each miRNA and change theme
  facet_wrap(~miRNA,scales="free")+ 
  theme_PhD(axis.text.size = 8) +
  theme(
    axis.title.x = element_blank(),
    strip.background = element_blank(),
    legend.key.size = (unit(0.7,"line")),
    legend.position = "bottom"
  ) +
  # extend facets by adding blank datapoints as defined with the function facet limits
  geom_blank(aes(y = y_min)) +
  geom_blank(aes(y = y_max)) + 
  # change colors of the plot elements and add y axis title
  scale_fill_manual(values = grey.colors(5,start=1,end=0.2))  +
  scale_y_continuous(expand = c(0, 0)) +
  ylab("miRNA expression (a.u.)")
Fig. 11: miRNA expression of the differentially expressed miRNAs with an interaction effect of cell line and irradiation in the two-way ANOVA (section 1.3.2). KAUVIR: cells irradiated with the irradiation device for the KAUVIR project. Results of interaction term in two-way ANOVA after fdr-adjustment are shown above the plots. Student’s t-test was used for group comparisons. ***: p < 0.001, **: p < 0.01, *: p < 0.05. geomean ± geosd. n = 4.

Fig. 11: miRNA expression of the differentially expressed miRNAs with an interaction effect of cell line and irradiation in the two-way ANOVA (section 1.3.2). KAUVIR: cells irradiated with the irradiation device for the KAUVIR project. Results of interaction term in two-way ANOVA after fdr-adjustment are shown above the plots. Student’s t-test was used for group comparisons. ***: p < 0.001, **: p < 0.01, *: p < 0.05. geomean ± geosd. n = 4.

NOTE: ** Apply bonferroni-correction for the 5 tests within each miRNA? **

All 4 miRNAs were upregulated in at least one cell line (miR-126-3p in SCC-13, miR-146a-5p in SCL-II, miR-30a-3p in SCC-12 and SCL-II and miR-7-5p in SCL-II). Although not significantly changed the same trend of upregulation can be observed for other cell lines as well, with an exception of miR-126-3p in Met-1 and SCC-12, miR-146a-5p in SCC-12 and SCC-13 and miR-7-5p in Met-1 and SCC-13 (which even shows a downregulation after irradiation, however not significantly).


Excursion: t-test

A t-test is a hypothesis test used to compare means of two samples a and b. The t-value for samples with equal variances (Student’s t-test) is calculated as:

\[ \begin{aligned} t = \frac{m_a-m_b}{\sqrt{\frac{S^2}{n_a} + \frac{S^2}{n_b}}} \end{aligned} \]

with ma the mean of sample a, mb the mean of sample b, na the sample size of a, nb the sample size of b and S2 being an estimator of the pooled variance:

\[ \begin{aligned} S^2 = \frac{\sum(x-m_a)^2 + \sum(x-m_b)^2}{n_a + n_b -2} \end{aligned} \] The degrees of freedom used to compare the calculated t-value to the critical t-value in a t-table are:

\[ \begin{aligned} df = n_{a} + n_{b} -2 \end{aligned} \]

For unequal variances (Welch’s t-test) the following formulas can be used:

\[ \begin{aligned} t = \frac{m_a-m_b}{\sqrt{\frac{S_a^2}{n_a} + \frac{S_b^2}{n_b}}} \end{aligned} \] with ma the mean of sample a, mb the mean of sample b, na the sample size of a, nb the sample size of b, Sa being the standard deviation of a and Sb being the standard deviation of b.

The degrees of freedom in this case are calculated as:

\[ \begin{aligned} df = \frac{(\frac{S_a^2}{n_a} +\frac{S_b^2}{n_b})}{\frac{S_a^4}{n_a^2(n_a -1)} + \frac{S_b^4}{n_b^2(n_b -1)}} \end{aligned} \]

1.4.2 Main effect Irradiation

Subsequently the irradiation main effect has been investigated to analyze miRNAs with a common UV-response in the different cell types (Fig. 12).

# filter miRNAs with a significant irradiation term but without significant interaction term
two_way_irradiation <- two_way_ANOVA %>%
  filter(Effect == "Irradiation" & p.adj < 0.05 & !miRNA %in% two_way_interaction) %>%
  pull(miRNA)

# t-test for the irradiation effect
pwc_irradiation <- dat%>%
  group_by(miRNA,cell_line) %>%
  pairwise_t_test(log_exp~Irradiation, pool.sd = F) %>% 
  filter(p < 0.05 & miRNA %in% two_way_irradiation) 

#calculate differential expression for Irradiation
diff_expr_irradiation <- pwc_irradiation %>%
  inner_join(folds) %>%
  select(miRNA, cell_line, p, log2FC) %>% 
  filter(abs(log2FC) > log2(1.5))
diff_expr_irradiation
dat_plot %>% 
  # only show differentially expressed miRNAs with a significant main effect "irradiation" term in two-way ANOVA but without significant interaction
  filter(miRNA %in% diff_expr_irradiation$miRNA) %>%
  ggplot(
    aes(
      x=cell_line,
      y=geomean,
      fill=Irradiation
    )
  ) + 
  # add errorbars with the defined limits
  geom_errorbar(
    limits,
    width=.2,
    position=position_dodge(0.5)
  ) +
  # add barplots to show geometric mean
  geom_bar(
    stat="identity",
    color="black",
    position=position_dodge(),
    width= 0.5
  ) +
  # split plot into separate plot for each miRNA and change theme
  facet_wrap(~miRNA,scales="free")+ 
  theme_PhD(axis.text.size = 8) +
  theme(
    axis.title.x = element_blank(),
    strip.background = element_blank(),
    legend.key.size = (unit(0.7,"line")),
    legend.position = "bottom"
  ) +
  # extend facets by adding blank datapoints as defined with the function facet limits
  geom_blank(aes(y = y_min)) +
  geom_blank(aes(y = y_max)) + 
  # change colors of the plot elements and add y axis title
  scale_fill_manual(values = grey.colors(5,start=1,end=0.2))  +
  scale_y_continuous(expand = c(0, 0)) +
  ylab("miRNA expression (a.u.)")
Fig. 12: miRNA expression of the differentially expressed miRNAs with an irradiation main effect in the two-way ANOVA but without significant interaction term (section 1.3.2). KAUVIR: cells irradiated with the irradiation device for the KAUVIR project. Results of irradiation term in two-way ANOVA after fdr-adjustment are shown above the plots. Student’s t-test was used for group comparisons. **: p < 0.01, *: p < 0.05. geomean ± geosd. n = 4.

Fig. 12: miRNA expression of the differentially expressed miRNAs with an irradiation main effect in the two-way ANOVA but without significant interaction term (section 1.3.2). KAUVIR: cells irradiated with the irradiation device for the KAUVIR project. Results of irradiation term in two-way ANOVA after fdr-adjustment are shown above the plots. Student’s t-test was used for group comparisons. **: p < 0.01, *: p < 0.05. geomean ± geosd. n = 4.

Significant upregulation could be detected for miR-135b-5p in SCC-13, miR-183-5p in SCC-13, miR-200a-3p in SCC-12, miR-30d-5p in SCC-13 and miR-424-5p in SCC-13. The miRNA expression shows a similar trend in the other cell lines as well with an exception of miR-135b-5p in Met-1 and SCL-II, miR-200a-3p in SCC-13 and miR-424-5p in Met-1. miR-205-5p is the only miRNA exhibiting a downregulation in all cell lines, with a significant downregulation in SCL-II. Furthermore, miR-205-5p shows the most significant general irradiation effect with p = 0.000253 in the two-way ANOVA. In summary UV irradiation seems to induce miRNA expression more often than inhibting miRNA expression with miR-205-5p being the only significantly downregulated miRNA out of totally 10 differentially expressed miRNAs between treated and control samples (results from section 1.4.1 and 1.4.2 combined).

Intriguingly, significant irradiation effects were only present in the three cell lines SCC-12, SCC-13 and SCL-II. This effect has been further investigated in section 1.5.

1.4.3 qPCR Validation

To validate the findings of section 1.4.1 and section 1.4.2 qPCR was performed. For the analysis four biological replicates – each measured twice to reduce technical variability – were used. Values of technical replicates were summarized by arithmetic mean. sno44 (Small nucleolar RNA SNORD44), sno48 (Small nucleolar RNA SNORD48) and miR-16-5p were used as house-keeping genes for normalisation as previously described (Vandesompele 2002). In contrast to Livak and Schmittgen ΔCt- and ΔΔCt-values were calculated as:

\[ \begin{aligned} ΔCt &= Ct_{ref} - Ct_{goi}\\ ΔΔCt &= ΔCt_{ctrl} - ΔCt_{trt} \end{aligned} \]

with Ctref representing the Ct value of the reference gene, Ctgoi representing the Ct value of the gene of interest, ΔCtctrl representing the ΔCt-value of the control samples and ΔCttrt representing the ΔCt-value of the irradiated samples. This way positive/negative ΔCt-values directly correspond to a higher/lower relative expression and positive/negative ΔΔCt-values directly correspond to a higher/lower fold-change without the need of taking inverse values.

# save url
url_file_val <- "https://raw.githubusercontent.com/MBender1992/PhD/Marc/Data/PhD_MB_qPCR_validation_Fireplex_20201015.csv" 

# load data
dat_qPCR <- read_csv(url(url_file_val)) %>% 
  rename(Name = Probenname) %>%
  # extract cell line out of ID string
  mutate(
    cell_line = str_replace_all(.$Name,"^\\d+_","") %>%
      str_replace_all("(_|\\s+)([:alpha:]+|\\d+|)\\d*[:alpha:]*","")
    ) %>%
  # extract treatment out of ID string
  mutate(
    treatment = str_replace_all(.$Name,"^\\d+_[:alpha:]{3}-([:alpha:]{2}|\\d+)(_|\\s+)","") %>%
      str_replace_all("(\\d*$|_([:alpha:]+|\\d+)\\d*[:alpha:]*)","") %>%
      str_replace_all("K0", "con"),
    treatment = tolower(treatment)
    ) %>% 
  # set everything to lower case letters for uniformity with the previous dataset
  mutate(gene_name = tolower(gene_name))

# load miR30d data (calculated separately as measured with different cycler and normalized with different HK genes)
url_miR30 <- "https://raw.githubusercontent.com/MBender1992/PhD/Marc/Data/miR-30d.rds" 
dat_miR30d <- readRDS(url(url_miR30))%>% 
  mutate(gene_name = tolower(gene_name))

dat_qPCR
# calculate geoMean of HK genes for each sample
dat_HK <- dat_qPCR %>% 
  group_by(Name, cell_line) %>%
  filter(gene_type == "HK") %>%
  mutate(geomean_HK = geoMean(mean_ct, na.rm=T)) %>%
  distinct(geomean_HK)

# calculate dCT values
dat_dCT <- inner_join(dat_qPCR, dat_HK) %>%
  ungroup() %>%
  filter(gene_type != "HK") %>%
  select(-gene_type) %>%
  mutate(dCT = geomean_HK - mean_ct)

## calculate ddCT
ddCT <- dat_dCT %>% 
  group_by(gene_name,cell_line) %>% 
  filter(treatment == "con") %>%
  summarize(ctrl_dCT = mean(dCT, na.rm = T)) %>%
  inner_join(dat_dCT %>% 
  filter(treatment != "con")) %>%
  mutate(ddCT = dCT - ctrl_dCT) %>%
  ungroup() %>%
  select(-c(Messung_1, Messung_2)) %>%
  # combine with previous results of miR-30d
  add_row(dat_miR30d) %>% 
  # rename column to "miRNA" for subsequent analysis
  rename(miRNA = gene_name) 

ΔΔCt-values were tested for significant differences from 0 with a one-sample t-test vs. 0 and compared to the Fireplex results (Fig. 11 & Fig. 12).

# one-sided t-test vs null
ddCT %>% group_by(cell_line,miRNA) %>% 
  t_test(ddCT~ 1, mu = 0) %>% 
  filter(p <= 0.05) %>% 
  arrange(miRNA)
# extract fold changes for each miRNA and cell line from Fireplex analysis
logFC_fireplex <- folds %>%
  filter(miRNA %in% c(ddCT$miRNA, "mir-30d-5p")) %>%
  select(-FC) %>%
  mutate(cell_line = str_replace_all(cell_line, "_","-")) %>%
  setNames(c("cell_line","miRNA", "logFC_Fireplex")) 

# join results from qPCR and Fireplex analysis
dat_plot <- ddCT %>%
  left_join(logFC_fireplex) %>%
  filter(!is.na(ddCT)) %>%
  mutate(miRNA = factor(miRNA, levels = mixedsort(unique(.$miRNA), decreasing = T)))

# define color sequence for the plot
cols <- c("#E2E2E2", "#DCDCDC" ,"#D1D1D1", "#C2C2C2", "#B1B1B1", "#9E9E9E", "#8A8A8A" ,"#747474" ,"#5E5E5E" ,"#474747")

# plot errorbars
dat_plot %>% 
  ggplot(aes(cell_line,ddCT,fill = cell_line)) +
  stat_boxplot(
    geom ='errorbar',position = position_dodge(0.48),
    size=0.5,
    width = 0.2
  ) +
  # add boxplot on top the errorbars
  geom_boxplot(
    color = "black", position = position_dodge(0.48), 
    mapping = aes(x = cell_line,y =ddCT),
    width=0.4
  ) +
  # plot points showing the mean of the Fireplex results
  geom_point(aes(cell_line,logFC_Fireplex), fill = "red", shape = 23) +
  facet_wrap(~miRNA, scales = "free") +
  geom_hline(yintercept = 0, lty = 3) +
  # change theme
  theme_minimal() + 
  theme(
    legend.position = "bottom",
    axis.line.y.left   = element_line(color = 'black'),
    axis.ticks.y = element_line(), 
    panel.grid  = element_blank(), 
    axis.text.x = element_blank(),
    axis.title.x = element_blank()
    )  +
  scale_y_continuous(limits = c(-2.2,2.2),breaks = seq(-2,2, 0.5)) +
  scale_color_manual(values = cols[seq(2,10,2)], name = "cell line") +
  scale_fill_manual(values = cols[seq(2,10,2)], name = "cell line") +
  ylab("log2-FC") 
Fig. 13: qPCR validation of Fireplex results (Fig 11. & Fig.12). Data were normalized to the geometric mean of miR-16, sno44 and sno48 expression. Shown are log2FC of irradiated samples in relation to controls. One sample t-test was used for comparison of log2FC versus 0. Red squares show the mean log2FC of irradiated vs. control samples in the Fireplex analysis. For readability, miRNA expression with |log2FC| > 2 in the Fireplex analysis is indicated by arrows. **: p < 0.01, *: p < 0.05. n = 4.

Fig. 13: qPCR validation of Fireplex results (Fig 11. & Fig.12). Data were normalized to the geometric mean of miR-16, sno44 and sno48 expression. Shown are log2FC of irradiated samples in relation to controls. One sample t-test was used for comparison of log2FC versus 0. Red squares show the mean log2FC of irradiated vs. control samples in the Fireplex analysis. For readability, miRNA expression with |log2FC| > 2 in the Fireplex analysis is indicated by arrows. **: p < 0.01, *: p < 0.05. n = 4.

Generally the qPCR results validate the Fireplex results as indicated by a similar direction of miRNA expression (when boxplots and red squares show common downregulation or upregulation, respectively). Contradictory results are present for miRNA-7-5p in SCC-12 (Fireplex: upregulated qPCR: downregulated), for miR-126-3p in SCC-12 (Fireplex: not changed, qPCR: upregulated) and SCC-13 (Fireplex: upregulated, qPCR: downregulated), for miR-135b-5p in SCC-13 (Fireplex: upregulated, qPCR: not changed), for miR-146-5p in SCC-12 (Fireplex: upregulated, qPCR: downregulated) and SCC-13 (Fireplex: downregulated, qPCR: upregulated), for miR 200a-3p in SCL-II (Fireplex: upregulated, qPCR: downregulated) and for miR-424-5p in SCC-13 (Fireplex: upregulated, qPCR: downregulated) and SCL-II (Fireplex: upregulated, qPCR: not changed). The best overlap between Fireplex and qPCR result could be observed for miR-205-5p with the log2FC of the Fireplex analysis being within the data range covered by the boxplot for each cell line. Because of this consistent downregulation and the role of miR-205-5p in cancer progression and metastasis in various cancer entitities, the role of this miRNA was chosen to be further elucidated in the context of cSCC progression (see section 2).

1.5 UV sensitivity of cell lines

As indicated in section 1.4.2 there were differences in the UV-responsiveness of different cell lines. This phenomenon was more thoroughly investigated in this section. To this end the absolute fold-change (to avoid negative and positive fold-changes cancelling out) between irradiated and control cells of all miRNAs between was averaged for each cell line and compared (Fig. 14).

# convert log2-fold changes to absolute log2-fold changes
dat_UV_sens <- folds %>% 
  ungroup()%>% 
  mutate(abslog2FC= abs(log2FC))

As the data was by definition not able to have negative values, non-normality was assumed and non-parametric tests were used for statistical testing of differences between groups.

# Kruskal Wallis test to test if there are any differences beteen cell lines
dat_UV_sens %>% 
  kruskal_test(abslog2FC~cell_line)

# Wilcoxon-Mann-Whitney U test to compare groups pairwise
dat_UV_sens %>% 
  dunn_test(abslog2FC~cell_line, p.adjust.method = "fdr")
# define position for jitter and text labels
pos <- position_jitter(width = 0.05, seed = 2)

# define labels to show the 3 most UV-responsive miRNAs
labels <- dat_UV_sens %>% 
  group_by(cell_line) %>%
  top_n(3, abslog2FC) %>% 
  mutate(label = miRNA)

# merge data with labels
dat_labelled <- left_join(dat_UV_sens,labels) %>%
  mutate(label = ifelse(is.na(label), "", label))

# plot
# add errorbars
plot_UV_sens <- dat_labelled %>% 
  ggplot(aes(cell_line,abslog2FC)) +
  stat_boxplot(
    geom ='errorbar',
    size=0.5,
    width = 0.2
  ) +
  # add boxplot
  geom_boxplot(
    color = "black",
    mapping = aes(x = cell_line,y = abslog2FC),
    outlier.shape =NA,
    width=0.4
  ) +
  # add points to display each individual miRNA
  geom_jitter(
    data =  filter(dat_labelled, label == ""),
    mapping = aes(x = cell_line,y = abslog2FC),
    width=0.1,
    alpha=0.3
  ) +
  # label the top 3 changed miRNAs with reds
  geom_jitter(
    data =  filter(dat_labelled, label != ""),
    mapping = aes(x = cell_line,y = abslog2FC, fill = "red"),
    shape = 21, 
    colour = "black",
    position = pos
  ) + 
  # show text label of the top 3 changed miRNAs
  geom_text_repel(
    data =  filter(dat_labelled, label != ""),
    mapping = aes(x = cell_line, y = abslog2FC, label = label),
    size = 3,
    position = pos
  ) + 
  theme_PhD(Legend=F) +
  theme(axis.text.x = element_text(angle=90, vjust= 0.4, hjust= 1)) +
  ylab("absolute log2-FC") +
  scale_y_continuous(limits = c(0,3.3), breaks = seq(0,3,0.5))
Fig. 14: UV-sensitivity of cell lines. The three most UV-responsive miRNAs are shown in red with name labels. n = 40.

Fig. 14: UV-sensitivity of cell lines. The three most UV-responsive miRNAs are shown in red with name labels. n = 40.

SCC-12 and SCC-13 show significantly higher absolute log2FC indicating a higher UV-responsiveness of these cell lines. Although not significantly changed, SCL-II also shows higher UV-sensitivity than Met-1 and Met-4. There are minor differences between cell lines in respect to which miRNAs are altered the most after UV irradiation, however miR-503-5p, miR-146a-5p and miR-30a-3p exhibit the highest differences in almost all cell lines. The lower UV-response in Met-1 and Met-4 might be due to a functional p53 protein and better DNA damage response.

2 miRNA expression in cSCC tissue

To identify possible miRNAs with oncogenic function in cSCC which are induced by UV-radiation we compared tissue samples of patients with cSCC (n = 5) with skin biopsies of healthy donors from sun-exposed(n = 5) and sun-protected (n = 6) areas. Although there were no evident differences between sun-protected and sun-exposed skin the cSCC tissue was clearly separated in a hierarchical clustering analysis (Fig. 15A). Two distinct clusters showed miRNAs overexpressed in tumor tissue (Cluster 1A) and suppressed in tumor tissue (Cluster 4A). The miRNAs in Cluster 1A are well known onco-miRs which are overexpressed in various tumors. Genes targeted by all 3 miRNAs are shown in Fig. 15B. A pathway analysis conducted with the R package RBiomiRGS incorporating all known (experimentally validated) targets of the miRNA triplet revealed only one pathway (KEGG_AXON_GUIDANCE) to be overrepresented in the gene set (Fig. 15D). This is most likely due to the low number of miRNAs and therefore a low number of target genes. On the other hand the genes targeted by at least 7 miRNAs of downregulated miRNAs in cSCC tissue are shown in Fig. 15C and a pathway analysis revealed the activation of pathways like KEGG_ERBB_SIGNALING_PATHWAY or KEGG_MAPK_SIGNALING_PATHWAY indicating activation of growth related signaling pathways in tumor tissue.

A second pathway analysis tool (miRTargetlink 2.0) yielded similar results with even more tumor related pathways overrepresented in the gene set targeted by the miRNAs in Cluster 4A. On top of growth related pathways there are also other tumor associated pathways like KEGG_VEGF_SIGNALING_PATHWAY (angiogenesis) or KEGG_ADHERENS_JUNCTION and KEGG_FOCAL_ADHESION (migration) that were enriched (in the top 20) using this webtool. In the top 20 enriched GO terms it was evident that the biological function of these miRNAs is closely related to the response to (UV) radiation and growth related signaling pathways.

In summary the miRNA expression between tumor tissue and skin (without differences between sun-exposed or sun-protected areas) is very distinct for certain miRNAs with a subset of downregulated miRNAs in tumor tissue involved in cell growth, cell migration, tumor progression and the response to UV radiation. This indicates that - although not altered in sun-exposed skin - these miRNAs are associated to a chronic and in the end failed response to genotoxic stress exerted by UV-radiation.

Taken together with the findings obtained in vitro there was only one miRNA that is downregulated in cSCC tissue as well as subsequent to chronic UV radiation in all 5 cell lines: miRNA-205. This miRNA might play a crucial role in the UV-induced carcinogenesis of cSCC. To examine the effects of miR-205 on a mechanistic level we performed in vitro knockdown experiments and investigated endpoints like cell growth, cell cylce distribution, apoptosis, migration, invasion as well as expression of prominent tumor associated genes targeted by miR-205.

Fig. 15: miRNA expression in cSCC tissue compared to sun-exposed and sun-protected skin. A: Hierarchical clustering analysis of differentially expressed miRNAs in cSCC tissue. B: Network analysis of miRNAs overexpressed in cSCC tissue. C: Network analysis of miRNAs suppressed in cSCC tissue. D: Pathway analysis miRNA targets shown in B generated with BiomiRGS. E: Pathway analysis of miRNA targets shown in C.

Fig. 15: miRNA expression in cSCC tissue compared to sun-exposed and sun-protected skin. A: Hierarchical clustering analysis of differentially expressed miRNAs in cSCC tissue. B: Network analysis of miRNAs overexpressed in cSCC tissue. C: Network analysis of miRNAs suppressed in cSCC tissue. D: Pathway analysis miRNA targets shown in B generated with BiomiRGS. E: Pathway analysis of miRNA targets shown in C.

3 Knockdown of miR-205-5p

3.1 Testing transfection conditions

To assess Knockdown efficiency, SCC-12 cells were seeded at 40.000 cells per well in a 24-well Plate, incubated for 24 h in standard cell culture conditions and transfected with different concentrations of antagomir-205 or a control oligo using the HiPerfect Transfection Reagent (Qiagen). Cells were harvested 24 h and 72 h after transfection, RNA was isolated and miR-205 expression was quantified via qPCR. The results are shown in figure 15.

# load and transform data
dat_qPCR <- read_csv("Data/PhD_MB_qPCR_transfection_mir_205_20210427.csv")%>% 
  rename(Name = Probenname) %>%
  mutate(time = str_extract(.$Name, "\\d+h")) %>%
  mutate(treatment = str_replace_all(.$Name, "_.+$","")) %>%
  mutate(condition = str_extract(.$Name, "\\d+nM.+microL"))

dat_mimic <- dat_qPCR %>% filter(type == "mimic")
dat_antago <- dat_qPCR %>% filter(type == "antago")

## antago mir 
ddCT_antago <- get_ddCT(dat_antago, ID = "Name", group.ctrl = "time", ct.val = "mean_ct") %>%
  mutate(condition = factor(condition, levels = c("5nM_1.5microL", "5nM_3microL", "10nM_3microL", "50nM_3microL")))

ddCT_antago %>%
  ggplot(aes(time, ddCT, fill = factor(condition))) +
  geom_errorbar(stat = "summary", fun.data = "mean_sdl", fun.args = list(mult = 1),
                  position = position_dodge(0.48), width = 0.25, size = 0.6)+
  geom_bar(stat = "summary", fun = "mean",
           color = "black", position = position_dodge(0.48),
           mapping = aes(x = time,y = ddCT),
           width=0.4
  )  + 
  geom_hline(yintercept= 0, lty = 2) +
  theme_PhD(axis.text.size = 10) +
  theme(
    axis.title.x = element_blank(),
    axis.line.x = element_blank(),
    axis.ticks.x = element_blank(),
    axis.text.x = element_blank(),
    strip.background = element_blank(),
    legend.position = "none"
  ) + 
  scale_y_continuous(limits = c(-4,2), breaks = seq(-4,2,1)) +
  scale_fill_brewer(palette = "Greys")
Fig. 16: Testing of different miR-205 Knockdown conditions. Data were normalized to the geometric mean of miR-16, sno44 and sno48 expression.

Fig. 16: Testing of different miR-205 Knockdown conditions. Data were normalized to the geometric mean of miR-16, sno44 and sno48 expression.

3.2 growth analysis

Fig. 17: Title. Text

Fig. 17: Title. Text

3.3 cell cycle distribution

Fig. 18: Cell cycle distribution of miR-205 Knockdown and control transfected cells. A: Cell cycle distribution of control transfected cells. B: Cell cycle distribution of cells transfected with antagomir-205. C: Barplot showing the percentage of G1, S and G2 phase in the differently treated cells at different timepoints.

Fig. 18: Cell cycle distribution of miR-205 Knockdown and control transfected cells. A: Cell cycle distribution of control transfected cells. B: Cell cycle distribution of cells transfected with antagomir-205. C: Barplot showing the percentage of G1, S and G2 phase in the differently treated cells at different timepoints.

4 TGF beta

The knockdown experiments with solely miR-205 did not show any differences in phenotypes of control or transfected cells, although miR-205 was stably downregulated. However target genes were only upregulated 24h post transfection and even showed downregulation 72h post transfection with a normalization of gene expression 144h post transfection. This indicates a negative feedback mechanism that ensures cell homeostasis. Moreover it is known that cancer is orchestrated by a multitude of potentially carcinogenic events - each of its own not sufficient for tumorigenesis - which in sum lead to cancer formation and progression. We therefore speculated that miR-205 suppression alone is not sufficient to increase migration or invasion processes connected to EMT (which is a crucial process on the way to metastases). Indeed it was shown that miR-205 regulates EMT together with TGF-beta, where miR-205 suppresses EMT and TGF-beta induces EMT. Furthermore TGF-beta is upregulated following UV irradiation and also frequently upregulated in cSCC tumors. Therefore it is likely that overexpression of TGF-beta in co-operation with downregulation of miR-205 induces EMT in a synergistic process.

To test this hypothesis the different endpoint analysis of section 3 were repeated and two additional treatment options were examined. (control, TGFb+, miR-205-, TGFb+ und miR-205-)

LS0tDQp0aXRsZTogSW5mbHVlbmNlIG9mIFVWIGlycmFkaWF0aW9uIG9uIGNTQ0MgcHJvZ3Jlc3Npb24vbWV0YXN0YXNpcyBhc3Nlc3NlZCBieSBlcGlnZW5ldGljDQogIGNoYW5nZXMgKG1pUk5BcykNCmF1dGhvcjogIk1hcmMgQmVuZGVyIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIHRvYzogeWVzDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdGhlbWU6IHVuaXRlZA0KICAgIHRvYzogeWVzDQotLS0NCg0KPHN0eWxlPg0KICBwLmNhcHRpb24gew0KICAgIGZvbnQtc2l6ZTogMC44ZW07DQogIH0NCmJvZHkgew0KICB0ZXh0LWFsaWduOiBqdXN0aWZ5fQ0KPC9zdHlsZT4NCg0KDQoNCiMgUHJlYW1ibGUNCg0KVGhpcyBkb2N1bWVudCBzZXJ2ZXMgYXMgYSBzdW1tYXJ5IG9mIHRoZSBkYXRhIGFuYWx5c2lzIGNvbmR1Y3RlZCBkdXJpbmcgbXkgUGhEIHRoZXNpcy4gSXQgaXMgc3RydWN0dXJlZCBjaHJvbm9sb2dpY2FsbHkgdG8gZW1waGFzaXplIGRlY2lzaW9uIG1ha2luZyBiYXNlZCBvbiB0aGUgcHJldmlvdXMgcmVzdWx0cy4gVGhlIGJhc2ljIHF1ZXN0aW9uIHdhcyBpZiBVViByYWRpYXRpb24gaW5mbHVlbmNlcyB0dW1vciBncm93dGggYmV5b25kIGluaXRpYXRpb24gZS5nLiBieSBpbmR1Y3Rpb24gb2YgZ2Vub21pYyBjaGFuZ2VzIG9yIGVwaWdlbmV0aWMgYWx0ZXJhdGlvbnMgcmVzdWx0aW5nIGluIHR1bW9yIHByb2dyZXNzaW9uIGFuZCBtZXRhc3Rhc2lzIG9mIGN1dGFuZW91cyBzcXVhbW91cyBjZWxsIGNhcmNpbm9tYSAoY1NDQykuIEFsbCBtaVJOQXMgaW4gdGhlIGZvbGxvd2luZyBzdHVkeSB3ZXJlIGh1bWFuIG1pUk5Bcy4gRGF0YSBpcyBhdmFpbGFibGUgYXQ6DQoNCiAgKyBGaXJlcGxleCBBbmFseXNpczogaHR0cHM6Ly9naXRodWIuY29tL01CZW5kZXIxOTkyL1BoRC9ibG9iL01hcmMvRGF0YS9QaERfTUJfRmlyZVBsZXhfY2hyb25pY19pcnJfMjAxOTA2MjAuY3N2DQogICsgcVBDUiB2YWxpZGF0aW9uIG9mIGZpcmVwbGV4IHJlc3VsdHM6IGh0dHBzOi8vZ2l0aHViLmNvbS9NQmVuZGVyMTk5Mi9QaEQvYmxvYi9NYXJjL0RhdGEvUGhEX01CX3FQQ1JfdmFsaWRhdGlvbl9GaXJlcGxleF8yMDIwMTAxNS5jc3YgDQoNCiMjIyBMb2FkaW5nIG9mIHJlcXVpcmVkIHBhY2thZ2VzDQoNCmBgYHtyLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0NCiMgZGF0YSB3cmFuZ2xpbmcgYW5kIGJhc2ljIHZpc3VhbGl6YXRpb24NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShnZ3B1YnIpDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpsaWJyYXJ5KGd0b29scykNCiMgc3RhdGlzdGljcw0KbGlicmFyeShyc3RhdGl4KQ0KbGlicmFyeShFbnZTdGF0cykgDQojIEhlYXRtYXANCmxpYnJhcnkoQ29tcGxleEhlYXRtYXApDQpsaWJyYXJ5KGNpcmNsaXplKQ0KIyBQQ0ENCmxpYnJhcnkoRmFjdG9NaW5lUikNCmxpYnJhcnkoZmFjdG9leHRyYSkNCiMgcGF0aHdheSBhbmFseXNpcw0KbGlicmFyeShSQmlvbWlyR1MpDQojIHBhcmFsbGVsIGNvbXB1dGluZyBhbmQgYWNjZXNzIG9mIGludGVybmV0IGRhdGENCmxpYnJhcnkoZGV2dG9vbHMpDQpsaWJyYXJ5KGRvUGFyYWxsZWwpDQoNCiMgc291cmNlIGN1c3RvbSBSIGZ1bmN0aW9ucw0Kc291cmNlX3VybCgiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL01CZW5kZXIxOTkyL2Jhc2Vfc2NyaXB0cy9NYXJjL1JfZnVuY3Rpb25zLlIiKSAgDQpgYGANCg0KDQojIDEuIFNjcmVlbmluZyBmb3IgVVYgaW5kdWNlZCBtaVJOQXMNCiMjIDEuMSBFeHBlcmltZW50YWwgc2V0dXAgYW5kIGRhdGEgaW5nZXN0aW9uDQpJbiBhIGZpcnN0IHN0ZXAgd2Ugc2NyZWVuZWQgNTEgbWFudWFsbHkgY3VyYXRlZCBtaVJOQXMgYXNzb2NpYXRlZCB3aXRoIGNTQ0Mgb3Igb3RoZXIgZXBpdGhlbGlhbCB0dW1vcnMgZm9yIFVWIGluZHVjZWQgY2hhbmdlcy4gVG8gdGhpcyBlbmQsIGZpdmUgZGlmZmVyZW50IGNhbmNlciBjZWxsIGxpbmVzIChTQ0wtSUksIE1ldC0xLCBNZXQtNCwgU0NDLTEyLCBTQ0MtMTM7IEZpZy4gMSkgd2VyZSBncm93biB1bmRlciBzdGFuZGFyZCBjZWxsIGN1bHR1cmUgY29uZGl0aW9ucyB3aXRoIERNRU0gKE1ldC0xLE1ldC00LCBTQ0wtSUkpIG9yIEZBRCAoU0NDLTEyLCBTQ0MtMTMpIGFzIGNlbGwgY3VsdHVyZSBtZWRpYS4gQ2VsbHMgd2VyZSBncm93biB0byA4MCAlIGNvbmZsdWVuY3kgYW5kIGV4cG9zZWQgdG8gMTAzIGtKL23CsiAocGh5c2ljYWwgZG9zZXM6IDI0Ni4wMSBKL23CsiBVVkIgKDI4MC0zMTUgbm0pOyAxMi41MCBrSi9twrIgVVZBICgzMTUtNDAwIG5tKTsgMjguMDMga0ovbcKyIFZJUyAoNDAwLTc1MCBubSk7IDYxLjc0IGtKL23CsiBJUi1BICg3NTAtMTIwMCBubSkpIHN1bmxpZ2h0LWVxdWl2YWxlbnQgcmFkaWF0aW9uIChTRVIpIHdpdGggYSBjdXN0b20tYnVpbHQgaXJyYWRpYXRpb24gZGV2aWNlIA0KKEtBVVZJUjogaHR0cHM6Ly93d3cuZm9uYS5kZS9kZS9tYXNzbmFobWVuL2ZvZXJkZXJtYXNzbmFobWVuL3N0cmFobGVuZm9yc2NodW5nLnBocCkuIFRoZSBjZWxscyB3ZXJlIHRyZWF0ZWQgZWlnaHQgdGltZXMgd2l0aCB0aGlzIGRvc2Ugb3ZlciBhIHRpbWUgY291cnNlIG9mIDQgd2Vla3MgKGlycmFkaWF0aW9uIHR3aWNlIGEgd2VlaykgdG8gc2ltdWxhdGUgYSBjaHJvbmljIFVWIGV4cG9zdXJlLiBGb3IgdGhlIGFuYWx5c2lzIDQgYmlvbG9naWNhbCByZXBsaWNhdGVzIHdlcmUgdXNlZC4gIA0KDQoNCiFbKipGaWcuIDE6IENlbGwgbGluZSBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIHR1bW9yIGNlbGwgbGluZXMgdXNlZCBpbiB0aGlzIHN0dWR5LioqICBUaGUgY2VsbCBsaW5lcyBleGhpYml0IGRpZmZlcmVudCBsZXZlbHMgb2YgZGlmZmVyZW50aWF0aW9uIHdpdGggU0NDLTEzIGJlaW5nIGhpZ2hseSBkaWZmZXJlbnRpYXRlZCBhbmQgU0NMLUlJIGJlaW5nIHVuZGlmZmVyZW50aWF0ZWQuIHA1MyBtdXRhdGlvbnMgYXJlIHByZXNlbnQgaW4gYWxsIGNlbGwgbGluZXMgZXhjZXB0IE1ldC0xIGFuZCBNZXQtNC4gTWV0LTEgYW5kIE1ldC00IGFyZSBjZWxsIGxpbmVzIGZyb20gdGhlIHNhbWUgcGF0aWVudCBpbiBkaWZmZXJlbnQgc3RhZ2VzIG9mIHRoZSB0dW1vci4pXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vTUJlbmRlcjE5OTIvUGhEL01hcmMvUmVzdWx0cy9jZWxsX2xpbmVfY2hhcmFjdGVyaXphdGlvbl9jcm9wcGVkLnBuZykNCg0KDQpBZnRlciBpcnJhZGlhdGlvbiwgY2VsbHMgd2VyZSBoYXJ2ZXN0ZWQgYW5kIHN1YmplY3RlZCB0byBGaXJlUGxleCBpbW11bm9hc3NheSAoYWJjYW07ICBodHRwczovL3d3dy5hYmNhbS5jb20vbmF2L211bHRpcGxleC1hc3NheXMvZmlyZXBsZXgtaW1tdW5vYXNzYXlzKSB0byBkZXRlY3QgY2hhbmdlcyBpbiBtaVJOQSBleHByZXNzaW9uIHVzaW5nIGJhcmNvZGUtbGFiZWxsZWQgcHJvYmVzLiBEYXRhIHdhcyBpbXBvcnRlZCB0byB0aGUgY29tcGxpbWVudGFyeSB3b3JrYmVuY2ggc29mdHdhcmUgYW5kIG5vcm1hbGl6ZWQgdG8gdGhlIDEyIG1vc3Qgc3RhYmxlIG1pUk5BcyB1c2luZyB0aGUgYnVpbHQtaW4gYWxnb3JpdGhtLg0KDQoNCmBgYHtyfQ0Kbm9ybWFsaXplcnMgPC0gYygibWlSLTIzYS0zcCIsIm1pUi0yM2ItM3AiLCAibWlSLTI0LTNwIiwgIm1pUi0yNmEtM3AiLCAibWlSLTMwYi0zcCIsICJtaVItMjItM3AiLCAibWlSLTE2LTVwIiwgIm1pUi0yMjEtM3AiLCAibWlSLTE1YS0zcCIsICJtaVItMjlhLTNwIiwgImxldC03Zi01cCIsICJtaVItMjljLTNwIikNCm5vcm1hbGl6ZXJzDQpgYGANCiAgIA0KU3Vic2VxdWVudGx5LCBkYXRhIHdhcyBpbXBvcnRlZCBpbnRvIFIgdXNpbmcgdGhlIGZvbGxvd2luZyBmdW5jdGlvbiwgdG8gZXhjbHVkZSBtaVJOQXMgd2l0aCBhIG1lZGlhbiBleHByZXNzaW9uIGJlbG93IGFuIGFyYml0cmFyeSB0aHJlc2hvbGQsIGNvbnZlcnQgZGF0YSBmcm9tIHdpZGUgdG8gdGlkeSBkYXRhIGFuZCBhZGQgYSBjb2x1bW4gd2l0aCBsb2cyLXRyYW5zZm9ybWVkIHZhbHVlcyBhcyBleHByZXNzaW9uIGRhdGEgZm9sbG93cyBhIGxvZy1ub3JtYWwgZGlzdHJpYnV0aW9uIChCZWFsIDIwMTcsIGh0dHBzOi8vaWVlZXhwbG9yZS5pZWVlLm9yZy9zdGFtcC9zdGFtcC5qc3A/YXJudW1iZXI9Nzk5MTYzOSkgOiAgIA0KDQpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQ0KbG9hZF9GaXJlcGxleF9kYXRhX1BoRCA8LSBmdW5jdGlvbihmaWxlbmFtZSwgdGhyZXNob2xkKQ0Kew0KICAjIGNoZWNrIGlmIHJlcXVpcmVkIHBhY2thZ2UgaXMgaW5zdGFsbGVkIGFuZCBsb2FkIGl0DQogIGlmICghcmVxdWlyZShkcGx5cikpIGluc3RhbGwucGFja2FnZXMoImRwbHlyIikNCiAgbGlicmFyeShkcGx5cikNCiAgDQogICNsb2FkIGRhdGEgYW5kIGNoYW5nZSBoeXBoZW5zIHRvIHVuZGVyc2NvcmVzIHNvIHIgZG9lcyBub3QgY29uZnVzZSBhIGh5cGhlbiB3aXRoIG1pbnVzDQogIGRhdCA8LSByZWFkX2NzdihmaWxlbmFtZSkNCiAgbmFtZXMoZGF0KSA8LSBzdHJfcmVwbGFjZV9hbGwobmFtZXMoZGF0KSwgIi0iLCJfIikNCiAgIyBjbGVhbiB1cCB0aGUgZGF0YSwgY29udmVydCB0byB0aWR5IGZvcm1hdCBhbmQgcmVwbGFjZSBuZWdhdGl2ZSBleHByZXNzaW9uIHZhbHVlcyB3aXRoIDAgYXMgZXhwcmVzc2lvbiAgICAgICAgY2Fubm90IGJlIG5lZ2F0aXZlDQogIGRhdF9mIDwtIGRhdCAlPiUgDQogICAgc2VsZWN0KC1NZXNzdW5nKSAlPiUNCiAgICBmaWx0ZXIoY2VsbF9saW5lICE9ICJIYUNhVCIpICU+JQ0KICAgIGdhdGhlcihtaVJOQSwgZXhwcmVzc2lvbiwgLWMoSUQsY2VsbF9saW5lLCBJcnJhZGlhdGlvbikpICU+JSANCiAgICBtdXRhdGUoZXhwcmVzc2lvbiA9IGlmZWxzZShleHByZXNzaW9uIDwgMCwgMCwgZXhwcmVzc2lvbikpICANCiAgIyBpbmRleCBtaVJOQXMgd2l0aCBhIG1lZGlhbiBleHByZXNzaW9uIGJlbG93IHRoZSB0aHJlc2hvbGQNCiAgaW5kIDwtIGRhdF9mICU+JQ0KICAgIGdyb3VwX2J5KG1pUk5BKSAlPiUNCiAgICBmaWx0ZXIobWVkaWFuKGV4cHJlc3Npb24sIG5hLnJtPVRSVUUpIDw9IHRocmVzaG9sZCkgJT4lDQogICAgLiRtaVJOQSAlPiUgDQogICAgdW5pcXVlKCkgDQogICMgb21pdCBpbmRleGVkIG1pUk5BcyBhbmQgYWRkIGxvZzItdHJhbnNmb3JtZWQgZXhwcmVzc2lvbiB2YWx1ZXMgDQogIGRhdF9mICU+JSANCiAgICBmaWx0ZXIoIW1pUk5BICVpbiUgaW5kKSAlPiUNCiAgICBtdXRhdGUobG9nX2V4cCA9IGxvZzIoZXhwcmVzc2lvbisxKSkgJT4lDQogICAgbXV0YXRlKG1pUk5BID0gc3RyX3JlcGxhY2VfYWxsKG1pUk5BLCAiaHNhXyIsICIiKSkgJT4lDQogICAgbXV0YXRlKG1pUk5BID0gc3RyX3JlcGxhY2VfYWxsKG1pUk5BLCAiXyIsIi0iKSkgJT4lDQogICAgbXV0YXRlKGNlbGxfbGluZSA9IHN0cl9yZXBsYWNlX2FsbChjZWxsX2xpbmUsICItIiwiXyIpKQ0KfQ0KDQp1cmxfZmlsZSA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL01CZW5kZXIxOTkyL1BoRC9NYXJjL0RhdGEvUGhEX01CX0ZpcmVQbGV4X2Nocm9uaWNfaXJyXzIwMTkwNjIwLmNzdiIgDQpkYXQgPC0gIGxvYWRfRmlyZXBsZXhfZGF0YV9QaEQoZmlsZW5hbWUgPSB1cmwodXJsX2ZpbGUpLCB0aHJlc2hvbGQgPSAyLjUpDQpkYXQNCmBgYA0KDQpUaGUgdGhyZXNob2xkIHdhcyBzZXQgdG8gMi41IChhLnUuKSBhcyB0aGlzIGlzIHRoZSBkZXRlY3Rpb24gbGltaXQgb2YgdGhlIGFzc2F5IGFzIGluZGljYXRlZCBieSB0aGUgbWFudWZhY3R1cmVycyBpbnN0cnVjdGlvbnMuIEFmdGVyIGFwcGx5aW5nIHRoaXMgdGhyZXNob2xkIDQwIG91dCBvZiB0aGUgaW50aWFsbHkgNTEgZXhhbWluZWQgbWlSTkFzIHJlbWFpbmVkIGluIHRoZSBhbmFseXNpcy4NClwNClwNCg0KIyMgMS4yIFByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMgKFBDQSkNCg0KIyMjIDEuMi4xIFRoZW9yZXRpY2FsIEJhY2tncm91bmQNCipOb3RlOiBFeHBsYW5hdGlvbiBmcm9tIFN0YXRxdWVzdCAoWW91VHViZSkgY29uY2VybmluZyBQQ0EuIEFuIGlsbHVzdHJhdGlvbiBvZiBwcmluY2lwYWwgY29tcG9uZW50cyBmb3IgYW4gZXhhbXBsZSB3aXRoIDIgdmFyaWFibGVzOioNCg0KRGF0YSBpcyBwbG90dGVkIGFzIHZhcjEgdnMgdmFyMiAodmFyMSBvbiB0aGUgeC1heGlzLCB2YXIyIG9uIHRoZSB5LWF4aXMpLiBUaGUgY2VudGVyIG9mIHRoaXMgZGF0YSBpcyBjYWxjdWxhdGVkIGFuZCB0aGUgZGF0YSBwb2ludHMgYXJlIHNoaWZ0ZWQgc28gdGhlIGNlbnRlciBpcyBhdCB0aGUgb3JpZ2luICgwLDApLiBIb3dldmVyLCB0aGUgcmVsYXRpb25zaGlwIG9mIHRoZSBkYXRhIHBvaW50cyBkdWUgdG8gdGhpcyByZXNjYWxpbmcgZGlkIE5PVCBjaGFuZ2UuIEEgcmFuZG9tIGxpbmUgZ29pbmcgdGhyb3VnaCB0aGUgb3JpZ2luIGlzIGZpdHRlZCwgdGhlIG9yaWdpbmFsIGRhdGEgcG9pbnRzIGFyZSBwcm9qZWN0ZWQgb250byB0aGlzIGxpbmUgYW5kIHRoZSBkaXN0YW5jZXMgZnJvbSB0aGUgb3JpZ2luIHRvIHRoZXNlIHByb2plY3RlZCBwb2ludHMgYXJlIGNhbGN1bGF0ZWQuIFRoZSBzdW0gb2Ygc3F1YXJlZCBkaXN0YW5jZXMgKHRvIGF2b2lkIG5lZ2F0aXZlIHZhbHVlcyBjYW5jZWxsaW5nIG91dCBwb3NpdGl2ZSBvbmVzKSBpcyBjYWxjdWxhdGVkIGFzIChTUyhkaXN0YW5jZXMpKTogDQokJA0KXGJlZ2lue2FsaWduZWR9DQpTUyhkaXN0YW5jZXMpID0gZF97MX1eMiArIGRfezJ9XjIgKyAuLi4gKyBkX3tufV4yDQpcZW5ke2FsaWduZWR9DQokJA0Kd2l0aCBuID0gc2FtcGxlIHNpemUNCg0KVGhlIGxpbmUgaXMgcm90YXRlZCBhcm91bmQgdGhlIG9yaWdpbiBhbmQgdGhlIGxpbmUgd2l0aCB0aGUgbWF4aW11bSBTUyhkaXN0YW5jZXMpIGJlY29tZXMgUEMxLiBUaGlzIGxpbmVzJyBzbG9wZSBjYW4gYmUgdXNlZCB0byBjYWxjdWxhdGUgc2luZ3VsYXIgdmVjdG9ycyBvciBFaWdlbnZlY3RvcnMgYnkgbG9va2luZyBhdCBob3cgbWFueSB1bml0cyB0aGUgbGluZSBnb2VzIGFsb25nIHRoZSB4LWF4aXMgaW4gcG9zaXRpdmUgZGlyZWN0aW9uIChiKSBpZiBtb3ZlZCAxIHVuaXQgaW4gcG9zaXRpdmUgZGlyZWN0aW9uIG9mIHRoZSB5LWF4aXMgKGMpLiBVc2luZyBweXRoYWdvcmVhbiB0aGVvcmVtIHRoZSBkaXN0YW5jZSBhICh2YWx1ZSBhbG9uZyB0aGUgc2xvcGUpIGlzIGVxdWFsIHRvOiAgDQokJA0KXGJlZ2lue2FsaWduZWR9DQphID0gXHNxcnR7Yl4yK2NeMn0NClxlbmR7YWxpZ25lZH0NCiQkDQp3aGljaCBjYW4gYmUgZWFzaWx5IGNhbGN1bGF0ZWQuIA0KICANCiAgKyBleGFtcGxlOiBUaGUgc2xvcGUgaXMgMC4yNSwgdGhlbiBiPTQgZm9yIGM9MSwgdXNpbmcgcHl0aGFnb3JlYW4gdGhlb3JlbTogDQogIA0KJCQNClxiZWdpbnthbGlnbmVkfQ0KYSA9IFxzcXJ0e2JeMitjXjJ9ID0gXHNxcnR7NF4yKzFeMn0gPSBcc3FydHsxNisxfSA9IDQuMTINClxlbmR7YWxpZ25lZH0NCiQkDQphLCBiIGFuZCBjIGFyZSB0aGVuIHNjYWxlZCBieSBmYWN0b3IgYSwgd2hpY2ggaW4gdHVybiBsZWFkcyB0byBhIGJlaW5nIDE6DQoNCiQkDQpcYmVnaW57YWxpZ25lZH0NCmEoc2NhbGVkKSAmID0gXGZyYWN7YX17YX0gPSAxXFwNCmIoc2NhbGVkKSAmID0gXGZyYWN7Yn17YX0gPSAwLjk3XFwNCmMoc2NhbGVkKSAmID0gXGZyYWN7Y317YX0gPSAwLjI0MlxcDQpcZW5ke2FsaWduZWR9DQokJA0KVGhpcyAxIHVuaXQgbG9uZyB2ZWN0b3IgY29uc2lzdGluZyBvZiBiKHNjYWxlZCkgaW4gdGhlIHgtZGlyZWN0aW9uIGFuZCBjKHNjYWxlZCkgaW4gdGhlIHktZGlyZWN0aW9uIGlzIHRoZSBFaWdlbnZlY3RvciBjb25zaXN0aW5nIG9mIDAuOTcgdW5pdHMgdmFyMSBhbmQgMC4yNDIgdW5pdHMgdmFyMi4gVGhlIEZhY3RvcnMgYihzY2FsZWQpIGFuZCBjKHNjYWxlZCkgYXJlIGNhbGxlZCBsb2FkaW5nIHNjb3JlcyBhbmQgY29ycmVzcG9uZCB0byB0aGUgaW1wb3J0YW5jZSBvZiBhIHBhcnRpY3VsYXIgdmFyaWFibGUgdG8gYSBwcmluY2lwYWwgY29tcG9uZW50Lg0KSW4gdGhpcyBleGFtcGxlIHRoZSBsb2FkaW5nIHNjb3JlcyB0ZWxsIHVzLCBpbiB0ZXJtcyBvZiBob3cgdGhlIHZhbHVlcyBhcmUgcHJvamVjdGVkIG9udG8gUEMxLCB2YXIxIGlzIDQgKDAuOTcvMC4yNDIpIHRpbWVzIG1vcmUgaW1wb3J0YW50IHRoYW4gdmFyMi4gDQoNCkluIHRoZSBjYXNlIG9mIG9ubHkgMiB2YXJpYWJsZXMgUEMyIGlzIHNpbXBseSB0aGUgbGluZSB0aGF0IGlzIHBlcnBlbmRpY3VsYXIgdG8gUEMxLiBUaGVuLCB0aGUgc2FtcGxlcyBhcmUgYWxzbyBwcm9qZWN0ZWQgb250byB0aGUgUEMyIGF4aXMuIFRoZXNlIHByb2plY3Rpb25zIG9mIGRhdGEgb24gUEMxIGFuZCBQQzIgb24gdGhlIFBDMSBhbmQgUEMyIGF4aXMgYXJlIHRoZW4gcm90YXRlZCBzbyBQQzEgaXMgaG9yaXpvbnRhbC4gQWZ0ZXJ3YXJkcyBvdXQgb2YgdGhlc2UgcHJvamVjdGlvbnMgbmV3IHBvc2l0aW9ucyBmb3IgdGhlIHNhbXBsZXMgYXJlIGdlbmVyYXRlZCBpbiB0aGUgUEMxIHZzIFBDMiBzcGFjZS4NCg0KVGhlIG1vcmUgZGltZW5zaW9ucyB0aGUgbW9yZSBjb21wbGV4IHRoaXMgcHJvY2VzcyBnZXRzLCB0aGUgUENzIGhvd2V2ZXIgYXJlIGFsd2F5cyBwZXJwZW5kaWN1bGFyIHRvIGVhY2ggb3RoZXIgYW5kIGFyZSB1bmNvcnJlbGF0ZWQuDQpUaGUgaXNzdWUgb2YgZ3Jvd2luZyBjb21wbGV4aXR5IHdoZW4gY29uc2lkZXJpbmcgbW9yZSB0aGFuIHRocmVlIGRpbWVuc2lvbnMgY2FuIGJlIHNvbHZlZCBtYXRoZW1hdGljYWxseSBhcyBhbm90aGVyIHdvcmQgZm9yIFNTKGRpc3RhbmNlcykgaXMgRWlnZW52YWx1ZXMsIHdoaWNoIGNhbiBiZSBjb21wdXRlZCBieSBtYXRyaXggYWxnZWJyYS4gT3V0IG9mIHRoZXNlIEVpZ2VudmFsdWVzLCB0aGUgRWlnZW52ZWN0b3JzIGNhbiBiZSBjb25zdHJ1Y3RlZCBhbmQgZXZlbnR1YWxseSB0aGUgUEMgbGluZXMgY2FuIGJlIGdlbmVyYXRlZCBldmVuIGZvciBoaWdoLWRpbWVuc2lvbmFsIGRhdGEuDQoNClRoZSB2YXJpYW5jZSBvZiB0aGUgUENzIGlzIHNpbXBseSB0aGUgRWlnZW52YWx1ZXMgb3IgU1MoZGlzdGFuY2VzKSBkaXZpZGVkIGJ5IHRoZSBzYW1wbGUgc2l6ZSBtaW51cyBvbmUgKG4tMSk6DQokJA0KXGJlZ2lue2FsaWduZWR9DQp2YXIoUENfe2l9KSAmPSBcZnJhY3tTUyhkaXN0YW5jZXMoUENfe2l9KSl9e24tMX1cXA0KXGVuZHthbGlnbmVkfQ0KJCQNClRoZXNlIHZhcmlhbmNlcyBjYW4gYmUgdXNlZCB0byBjYWxjdWxhdGUgdGhlIHByb3BvcnRpb24gb2YgdmFyaWFuY2UgaW4gdGhlIGRhdGEgZXhwbGFpbmVkIGJ5IGVhY2ggUEMgKHZhcmlhbmNlIGV4cGxhaW5lZCkgdXNpbmcgdGhlIHN1bSBvZiB2YXJpYW5jZXMgOg0KJCQNClxiZWdpbnthbGlnbmVkfQ0KU3VtKHZhcmlhbmNlcykgPSBcc3VtX3tpID0gMX1ebiB2YXIoUENfe2l9KQ0KXGVuZHthbGlnbmVkfQ0KJCQNClRvIGdldCB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGZvciBlYWNoIFBDLCB0aGUgdmFyaWFuY2Ugb2YgdGhlIHJlc3BlY3RpdmUgUEMgaXMgZGl2aWRlZCBieSB0aGUgc3VtIG9mIHZhcmlhbmNlcyBvZiBhbGwgUENzLg0KDQorIEV4YW1wbGUgdG8gY2FsY3VsYXRlIHZhcmlhbmNlIGV4cGxhaW5lZCBmb3IgUEMxIGlmIHZhcihQQzEpIGlzIDE1IGFuZCB2YXIoUEMyKSBpcyAzOg0KDQokJA0KXGJlZ2lue2FsaWduZWR9DQpcZnJhY3t2YXIoUENfezF9KX17XHN1bV97aSA9IDF9Xm4gdmFyKFBDX3tpfSl9ID0gXGZyYWN7dmFyKFBDX3sxfSl9e3ZhcihQQ197MX0pK3ZhcihQQ197Mn0pfSA9IFxmcmFjezE1fXsxNSszfSA9IDAuOFxiYXIzID0gODMuXGJhcjMgXCBcJQ0KXGVuZHthbGlnbmVkfQ0KJCQNCg0KSW4gdGhpcyBleGFtcGxlIFBDMSB3b3VsZCBleHBsYWluIDgzLjMgJSBvZiB0aGUgdmFyaWFuY2UgaW4gdGhlIGRhdGEgYW5kIFBDMiB3b3VsZCBleHBsYWluIDE2LjcgJSBvZiB0aGUgdmFyaWFuY2UgaW4gdGhlIGRhdGEuIEluIFIgdGhlIHByY29tcCBmdW5jdGlvbiBnZW5lcmF0ZXMgMyBwYXJhbWV0ZXJzOiB4LCBzZGV2IGFuZCByb3RhdGlvbg0KDQorICoqeCoqIGNvbnRhaW5zIHRoZSBQQ3MgdG8gZHJhdyBhIGdyYXBoDQorICoqc2RldioqIGlzIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIFBDcyBhbmQgY2FuIGJlIHRyYW5zZmVycmVkIHRvIHRoZSB2YXJpYW5jZSBieSBzcXVhcmluZyBzZGV2IGFuZCBzdWJzZXF1ZW50bHkgYmUgdXNlZCB0byBjYWxjdWxhdGUgdGhlIHZhcmlhbmNlIGV4cGxhaW5lZA0KKyAqKnJvdGF0aW9uKiogY29ycmVzcG9uZHMgdG8gdGhlIGxvYWRpbmcgc2NvcmVzIHdoaWNoIHNob3cgdGhlIGltcG9ydGFuY2Ugb2YgdmFyaWFibGVzIGluIHJlc3BlY3QgdG8gZWFjaCBQQw0KXA0KXA0KDQojIyMgMS4yLjIgQW5hbHlzaXMNCg0KQWZ0ZXJ3YXJkcywgZGF0YSB3YXMgYW5hbHl6ZWQgZm9yIGdlbmVyYWwgY2hhbmdlcyBiZXR3ZWVuIGNlbGwgbGluZXMuIEFzIGV4cGxvcmF0aXZlIGFuYWx5c2lzLFBDQSB3YXMgY2hvc2VuIGFzIGl0IGJyZWFrcyBkb3duIG11bHRpZGltZW5zaW9uYWwgZGF0YSBhbmQgZmFjaWxpdGF0ZXMgdmlzdWFsaXphdGlvbiBvZiB0aGUgdW5kZXJseWluZyBkYXRhIHN0cnVjdHVyZS4gDQoNCmBgYHtyfQ0KIyB0cmFuc2Zvcm0gZGF0YSBmb3IgdGhlIGZvcm1hdCByZXF1aXJlZCBieSAiUENBIg0KZGF0X1BDQSA8LSBkYXQgJT4lIA0KICBzZWxlY3QoLWMoZXhwcmVzc2lvbikpICU+JQ0KICBzcHJlYWQobWlSTkEsIGxvZ19leHApICU+JQ0KICBtdXRhdGUoY2VsbF9saW5lID0gc3RyX3JlcGxhY2VfYWxsKGNlbGxfbGluZSwgIl8iLCItIikpDQoNCiMgc2NhbGUgZGF0YSBhbmQgcGVyZm9ybSBQQ0ENCnJlcy5wY2EgPC0gUENBKGRhdF9QQ0FbLCAtYygxOjMpXSwgIHNjYWxlLnVuaXQgPSBULCBuY3AgPSA1LCBncmFwaCA9IEYpDQoNCiMgZXh0cmFjdCByZXN1bHRzIGFuZCBjaG9zZSB3aGljaCBQQ3MgdG8gdXNlDQplaWcudmFsIDwtIGdldF9laWdlbnZhbHVlKHJlcy5wY2EpDQoNCmhlYWQoZWlnLnZhbCkNCg0KYGBgDQoNCkFzIHNob3duIGFib3ZlLCB3aGVuIHVzaW5nIHRocmVlIGRpbWVuc2lvbnMsIHRoZSBhbmFseXNpcyBpcyBhYmxlIHRvIGV4cGxhaW4gbW9yZSB0aGFuIDcwICUgb2YgdGhlIHZhcmlhbmNlIGluIHRoZSBkYXRhLiBBcyB3ZSBhZGQgbW9yZSBkaW1lbnNpb25zIHRoZSBleHBsYW5hdGlvbiBpbXByb3ZlcywgbmF0dXJhbGx5LCBob3dldmVyIGZvciB2aXN1YWxpemF0aW9uIHJlYXNvbnMgYW5kIHRoZSBjb21wbGV4aXR5IG9mIGltYWdpbmluZyBtb3JlIHRoYW4gdGhyZWUgZGltZW5zaW9ucywgb25seSB0aGUgY29tcGFyaXNvbiBvZiBQQzEgdnMgUEMyLCBQQzEgdnMgUEMzIGFuZCBQQzIgdnMgUEMzIGFyZSBzaG93biAoRmlnLiAyKS4gIA0KDQpgYGB7cn0NCmZ2aXpfcGNhX2luZCgNCiAgcmVzLnBjYSwNCiAgIyBGaWxsIGluZGl2aWR1YWxzIGJ5IGdyb3Vwcw0KICBnZW9tLmluZCA9ICJwb2ludCIsDQogIGZpbGwuaW5kID0gZGF0X1BDQSRjZWxsX2xpbmUsDQogIGNvbC5pbmQgPSAiYmxhY2siLA0KICBwb2ludHNoYXBlID0gMjEsIA0KICBwb2ludHNpemUgPSBkYXRfUENBJElycmFkaWF0aW9uLA0KICBwYWxldHRlID0gImpjbyIsDQogIGFkZEVsbGlwc2VzID0gVCwNCiAgYXhlcyA9IGMoMSwgMiksDQogICMgVmFyaWFibGVzDQogIGFscGhhLnZhciA9MC41LA0KICBtZWFuLnBvaW50ID0gRiwNCiAgZWxsaXBzZS5sZXZlbD0wLjgsDQogIGxlZ2VuZC50aXRsZSA9IGxpc3QoZmlsbCA9ICJDZWxsIGxpbmUiKQ0KKSArIA0KICBzY2FsZV9zaXplX21hbnVhbCh2YWx1ZXMgPSBjKDIsNCkpDQpgYGANCiFbKipGaWcuIDI6IFBDQSBvZiB0aGUgaXJyYWRpYXRlZCBjZWxsIGxpbmVzIE1ldC0xLCBNZXQtNCwgU0NDLTEyLCBTQ0MtMTMsIFNDTC1JSS4qKiBMYXJnZSBjaXJjbGVzIHNob3cgaXJyYWRpYXRlZCBzYW1wbGVzLCBzbWFsbCBjaXJjbGVzIGluZGljYXRlIGNvbnRyb2wgc2FtcGxlcy4gRGltMSBpcyBlcXVpdmFsZW50IHRvIFByaW5jaXBhbCBDb21wb25lbnQgMSAoUEMxKSwgZXRjLiBFbGxpcHNlcyBhcmUgZHJhd24gYXJvdW5kIHRoZSByZXNwZWN0aXZlIGNlbGwgbGluZXMgZm9yIGlsbHVzdHJhdGlvbi4gVGhlIHZhcmlhbmNlIGV4cGxhaW5lZCBpcyBzaG93biBpbiBwYXJlbnRoZXNlcy4gTk9URTogVGhlIGNvZGUgYWJvdmUgb25seSBzaG93cyB0aGUgcGxvdCBmb3IgUEMxIHZzIFBDMiAoYXhlcyA9IGMoMSwyKSkuIFRoZSBpbWFnZSB3YXMgZ2VuZXJhdGVkIGJ5IHNhdmluZyB0aGUgMyBkaWZmZXJlbnQgaW1hZ2VzIChBOiBQQzEgdnMgUEMyLEI6IFBDMSB2cyBQQzMsQzogUEMyIHZzIFBDMykgYW5kIGNvbWJpbmluZyB0aGVtIGluIHBvd2VyIHBvaW50LiBuID0gNC5dKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9NQmVuZGVyMTk5Mi9QaEQvTWFyYy9SZXN1bHRzL1BDQV9jb21iaW5lZC5wbmcpDQoNCg0KQSBzZXBhcmF0aW9uIG9mIFNDQy0xMi9TQ0MtMTMgYW5kIE1ldC0xL01ldC00IGlzIGV2aWRlbnQgYWxvbmcgdGhlIFBDMSBheGlzLCBQQzIgc2VwYXJhdGVzIFNDTC1JSSBmcm9tIGFsbCBvdGhlciBjZWxsIGxpbmVzLiBXaXRoaW4gY2x1c3RlcnMgKGVsbGlwc2VzKSBpcnJhZGlhdGVkIGNlbGxzIChiaWcgY2lyY2xlcykgZm9ybSBzdWJjbHVzdGVycyBpbiB0aGUgUEMxIHZzIFBDMiBwbG90IGFzIHdlbGwgYXMgaW4gdGhlIFBDMiB2cyBQQzMgcGxvdCBpbiBhbGwgY2VsbCBsaW5lcyBhbmQgaW4gdGhlIFBDMSB2cyBQQzMgcGxvdCBpbiBNZXQtNCwgU0NDLTEzLCBhbmQgU0NMLUlJLiBIb3dldmVyIHRoZSBpcnJhZGlhdGlvbiBlZmZlY3RzIGFyZSBub3QgYXMgcHJvbm91bmNlZCBhcyB0aGUgY2VsbCBsaW5lIGVmZmVjdHMgaW5kaWNhdGluZyBhIGxhcmdlciBkaWZmZXJlbmNlIGluIHRoZSBtaVJOQSBleHByZXNzaW9uIGJldHdlZW4gY2VsbCBsaW5lcyB0aGFuIGJldHdlZW4gdHJlYXRlZCBhbmQgY29udHJvbCBjZWxscy4gDQoNClRvIGZ1cnRoZXIgaW52ZXN0aWdhdGUgdGhlIGluZGljYXRlZCBpcnJhZGlhdGlvbiBlZmZlY3QgYSBzZWNvbmQgUENBIHBsb3QgaGFzIGJlZW4gZHJhd24gd2l0aCBhbiBlbXBoYXNpcyBvbiB0cmVhdG1lbnQgcmF0aGVyIHRoYW4gY2VsbCBsaW5lIChGaWcuIDMpLg0KDQpgYGB7cn0NCmZ2aXpfcGNhX2JpcGxvdCgNCiAgcmVzLnBjYSwNCiAgIyBGaWxsIGluZGl2aWR1YWxzIGJ5IGdyb3Vwcw0KICBnZW9tLmluZCA9ICJwb2ludCIsDQogIHBvaW50c2hhcGUgPSAyMSwNCiAgcG9pbnRzaXplID0gMi41LA0KICBmaWxsLmluZCA9IGRhdF9QQ0EkSXJyYWRpYXRpb24sDQogIGNvbC5pbmQgPSAiYmxhY2siLA0KICBwYWxldHRlID0gImpjbyIsDQogICMgQ29sb3IgdmFyaWFibGUgYnkgZ3JvdXBzDQogIGNvbC52YXIgPSAiY29zMiIsDQogIGFscGhhLnZhciA9IDAuMywNCiAgYXhlcyA9IGMoMSwyKSwNCiAgYWRkRWxsaXBzZXMgPSBULA0KICBlbGxpcHNlLmxldmVsPTAuOCwNCiAgbGVnZW5kLnRpdGxlID0gbGlzdChmaWxsID0gIklycmFkaWF0aW9uIiwgY29sb3IgPSAicXVhbGl0eSBvZiByZXByZXNlbnRhdGlvbiIpLA0KICByZXBlbCA9IFRSVUUgICAgICAgICMgQXZvaWQgbGFiZWwgb3ZlcnBsb3R0aW5nDQopKyANCiAgc2NhbGVfc2l6ZV9tYW51YWwodmFsdWVzID0gYygyLDQpKQ0KYGBgDQohWyoqRmlnLiAzOiBQQ0Egb2YgdGhlIGlycmFkaWF0ZWQgY2VsbCBsaW5lcyBNZXQtMSwgTWV0LTQsIFNDQy0xMiwgU0NDLTEzLCBTQ0wtSUkuKiogTGFyZ2UgY2lyY2xlcyByZXByZXNlbnQgdGhlIG1lYW4uIERpbTEgaXMgZXF1aXZhbGVudCB0byBQcmluY2lwYWwgQ29tcG9uZW50IDEgKFBDMSksIGV0Yy4gRWxsaXBzZXMgYXJlIGRyYXduIGFyb3VuZCB0aGUgdHJlYXRtZW50IGNvbmRpdGlvbnMuIEFycm93cyBpbmRpY2F0ZSBjb3JyZWxhdGlvbiBvZiBtaVJOQSB3aXRoIHRoZSByZXNwZWN0aXZlIFByaW5jaXBhbCBDb21wb25lbnQuIG1pUk5BcyBzaGFyaW5nIGEgc2ltaWxhciBhbmdsZSBpbiB0aGUgcGxvdCBhcmUgcG9zaXRpdmVseSBjb3JyZWxhdGVkLCBtaVJOQXMgd2l0aCBvcnRob2dvbmFsIGFycm93cyBhcmUgdW5jb3JyZWxhdGVkIGFuZCBtaVJOQXMgd2l0aCBhbiBhbmdsZSBvZiAxODDCsCBhcmUgbmVnYXRpdmVseSBjb3JyZWxhdGVkLiBUaGUgdmFyaWFuY2UgZXhwbGFpbmVkIGlzIHNob3duIGluIHBhcmVudGhlc2VzLiBOT1RFOiBUaGUgY29kZSBhYm92ZSBvbmx5IHNob3dzIHRoZSBwbG90IGZvciBQQzEgdnMgUEMyIChheGVzID0gYygxLDIpKS4gVGhlIGltYWdlIHdhcyBnZW5lcmF0ZWQgYnkgc2F2aW5nIHRoZSAzIGRpZmZlcmVudCBpbWFnZXMgKEE6IFBDMSB2cyBQQzIsQjogUEMxIHZzIFBDMyxDOiBQQzIgdnMgUEMzKSBhbmQgY29tYmluaW5nIHRoZW0gaW4gcG93ZXIgcG9pbnQuIG4gPSA0LiBdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9NQmVuZGVyMTk5Mi9QaEQvTWFyYy9SZXN1bHRzL1BDQV9jb21iaW5lZF9pcnJhZGlhdGlvbi5wbmcpDQoNCkZpZy4gMyBzaG93cyBhIHB1dGF0aXZlIGlycmFkaWF0aW9uIGVmZmVjdCBjb3JyZWxhdGluZyB3aXRoIFBDMiBhbmQgUEMzLkFsdGhvdWdoIHRoZSBtYWpvcml0eSBvZiB2YXJpYW5jZSBpbiB0aGUgZGF0YSBvcmlnaW5hdGVzIGZyb20gY2VsbCBsaW5lIGRpZmZlcmVuY2VzIGFzIGluZGljYXRlZCBpbiBGaWcuIDIsIGEgc21hbGxlciBidXQgc3RpbGwgc3Vic3RhbnRpYWwgcG9ydGlvbiBvZiB0aGUgdmFyaWFuY2UsIGluZGVlZCwgc3RlbXMgZnJvbSB0aGUgaXJyYWRpYXRpb24gdHJlYXRtZW50LiBUaGVzZSB0d28gZWZmZWN0cyAtICpjZWxsIGxpbmUgZWZmZWN0KiBhbmQgKmlycmFkaWF0aW9uIGVmZmVjdCogLSB3ZXJlIGZ1cnRoZXIgYW5hbHl6ZWQuIA0KXA0KXA0KDQojIyAxLjMgSW52ZXN0aWdhdGlvbiBvZiB0aGUgY2VsbCBsaW5lIGVmZmVjdA0KDQpUbyBnZXQgYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZiB0aGUgY2VsbCBsaW5lIGVmZmVjdCBhIGNsdXN0ZXJpbmcgYW5hbHlzaXMgb24gZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIG1pUk5BcyBpbiBjb250cm9sIGNlbGxzIHdhcyBwZXJmb3JtZWQuVGhlIHN0YXRpc3RpY2FsIGFuYWx5c2lzIHVuZGVybHlpbmcgdGhlIGNoYXJhY3Rlcml6YXRpb24gYXMgKmRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCogaXMgc2hvd24gYXMgZm9sbG93czogDQoNCg0KIyMjIDEuMy4xIENoZWNraW5nIGFzc3VtcHRpb25zIGZvciBzdGF0aXN0aWNhbCB0ZXN0cw0KICANCg0KYGBge3J9DQojIGNoZWNrIGZvciBvdXRsaWVycyANCm91dGwgPC0gZGF0ICU+JSANCiAgZ3JvdXBfYnkoY2VsbF9saW5lLElycmFkaWF0aW9uLCBtaVJOQSkgJT4lDQogIGlkZW50aWZ5X291dGxpZXJzKGxvZ19leHApIA0KYW55KG91dGwkaXMuZXh0cmVtZSkNCmBgYA0KDQpObyBleHRyZW1lIG91dGxpZXJzIHdlcmUgcHJlc2VudCBpbiB0aGUgYW5hbHlzaXMuIFRlc3RpbmcgZm9yIG5vcm1hbGl0eSBvciBob21vZ2VuZWl0eSBvZiB2YXJpYW5jZXMgd2FzIG5vdCBpbmRpY2F0ZWQgaW4gdGhpcyBzdHVkeSBhcyB0aGUgc2FtcGxlIHNpemUgd2FzIHRvbyBzbWFsbCAobiA9IDQpIHRvIGRldGVjdCBkZXZpYXRpb25zIGZyb20gc2FpZCBhc3N1bXB0aW9ucy4gVGhlcmVmb3JlLCAgYSB0aGVvcmV0aWNhbCBhcHByb2FjaCBoYXMgYmVlbiB1c2VkIHRvIHNvbHZlIHRoaXMgcHJvYmxlbToNCg0KKiBBcyBleHBsYWluZWQgaW4gc2VjdGlvbiAxLjEsIGV4cHJlc3Npb24gZGF0YSBmb2xsb3dzIGEgbG9nLW5vcm1hbCBkaXN0cmlidXRpb24sIHRodXMgbG9nLXRyYW5zZm9ybWVkIHZhbHVlcyB3ZXJlIHVzZWQgZm9yIHN0YXRpc3RpY2FsIGFuYWx5c2lzIA0KKiBUbyBkZWFsIHdpdGggcG9zc2libGUgaGV0ZXJvZ2VuZWl0eSBvZiB2YXJpYW5jZXMsIEFOT1ZBIHdpdGggaGV0ZXJvc2NlZGFzdGljaXR5IGNvcnJlY3RlZCBjb3ZhcmlhbmNlIG1hdHJpY2VzIChXaGl0ZSAxOTgwLCBMb25nIGFuZCBFcnZpbiAyMDAwKSBhbmQgcG9zdC1ob2MgcGFpcndpc2UgdC10ZXN0IHdpdGggdW5lcXVhbCB2YXJpYW5jZXMgd2VyZSBlbXBsb3llZCAod2hpdGUuYWRqdXN0ID0gVFJVRSBpbiBBTk9WQSBhbmQgcG9vbC5zZCA9IFRSVUUgaW4gcGFpcndpc2UgdC10ZXN0KQ0KDQojIyMgMS4zLjIgVHdvLVdheSBBTk9WQQ0KDQoNCiMjIyMgRXhjdXJzaW9uOiBBTk9WQQ0KDQoNCg0KIyMjIyBBbmFseXNpcyANCkEgdHdvLXdheSBBTk9WQSB3YXMgY29uZHVjdGVkIGF0IGVhY2ggbGV2ZWwgb2YgdGhlIGZhY3RvciAqbWlSTkEqIHRvIGRldGVybWluZSB0aGUgZWZmZWN0cyBvZiBjZWxsIGxpbmUgYW5kIGlycmFkaWF0aW9uIG9uIG1pUk5BIGV4cHJlc3Npb24uIFN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSB3YXMgYWNjZXB0ZWQgZm9yIHAgPCAwLjA1IGFmdGVyIGZkci1hZGp1c3RtZW50IChCZW5qYW1pbmkgJiBIb2NoYmVyZyAxOTk1KSBmb3IgdHdvLXdheSBpbnRlcmFjdGlvbnMgYW5kIHNpbXBsZSBtYWluIGVmZmVjdHMuIFRoZSByZXN1bHRzIG9mIHRoZSB0d28td2F5IEFOT1ZBIGFyZSBzaG93biBleGVtcGxhcnkgYmVsb3cuDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQ0KIyAyLXdheSBBTk9WQSB3aXRoIG1pUk5BIGFzIG1vZGVyYXRvciB2YXJpYWJsZQ0KdHdvX3dheV9BTk9WQSA8LSBkYXQgJT4lDQogIGdyb3VwX2J5KG1pUk5BKSAlPiUNCiAgIyBwZXJmb3JtIEFOT1ZBIHdpdGggaGNjbSBjb3JyZWN0aW9uICh3aGl0ZS5hZGp1c3QgPSBUUlVFKQ0KICBhbm92YV90ZXN0KGxvZ19leHAgfiBjZWxsX2xpbmUqSXJyYWRpYXRpb24sIHdoaXRlLmFkanVzdCA9IFQpICU+JQ0KICBhZGp1c3RfcHZhbHVlKG1ldGhvZCA9ICJmZHIiKSANCnR3b193YXlfQU5PVkENCmBgYA0KDQpJbiA1IG91dCBvZiB0aGUgNDAgbWlSTkFzIHRoZXJlIHdhcyBhbiBpbnRlcmFjdGlvbiBlZmZlY3QgcHJlc2VudCAobWlSLTEyNi0zcCwgbWlSLTE0NmEtNXAsIG1pUi0zMGEtM3AsIG1pUi0zMGItNXAsIG1pUi03LTVwKS4gQSBjZWxsIGxpbmUgbWFpbiBlZmZlY3Qgd2FzIG9ic2VydmVkIGluIDM4IG91dCBvZiA0MCBtaVJOQXMgKGVhY2ggb2YgdGhlIG1pUk5BcyBzaG93aW5nIGFuIGludGVyYWN0aW9uIGVmZmVjdCBhbHNvIHNob3dlZCBhIHNpZ2ZuaWZjYW50IG1haW4gZWZmZWN0KS4gT25seSBmb3IgbWlSTkEgbGV0LTdmLXAgYW5kIG1pUi0zMGQtNXAgbm8gY2VsbCBsaW5lIGVmZmVjdCBjb3VsZCBiZSBvYnNlcnZlZCBhZnRlciBhZGp1c3RpbmcgZm9yIG11bHRpcGxlIHRlc3RpbmcuIA0KDQoNCmBgYHtyfQ0KIyBzaG93IGludGVyYWN0aW9uDQp0d29fd2F5X2ludGVyYWN0aW9uIDwtIHR3b193YXlfQU5PVkEgJT4lDQogIGZpbHRlcihFZmZlY3QgPT0gImNlbGxfbGluZTpJcnJhZGlhdGlvbiIgJiBwLmFkaiA8IDAuMDUpICU+JQ0KICBwdWxsKG1pUk5BKQ0KdHdvX3dheV9BTk9WQSAlPiUgDQogIGZpbHRlcihtaVJOQSAlaW4lIHR3b193YXlfaW50ZXJhY3Rpb24gJiBFZmZlY3QgPT0gImNlbGxfbGluZTpJcnJhZGlhdGlvbiIpIA0KDQojIHNob3cgbWFpbiBjZWxsIGxpbmUgZWZmZWN0DQp0d29fd2F5X2NlbGw8LSB0d29fd2F5X0FOT1ZBICU+JQ0KICBmaWx0ZXIoRWZmZWN0ID09ICJjZWxsX2xpbmUiICYgcC5hZGogPCAwLjA1KSAlPiUNCiAgcHVsbChtaVJOQSkNCnR3b193YXlfQU5PVkEgJT4lIA0KICBmaWx0ZXIobWlSTkEgJWluJSB0d29fd2F5X2NlbGwgJiBFZmZlY3QgPT0gImNlbGxfbGluZSIpIA0KDQojIG5vIGVmZmVjdA0KdHdvX3dheV9BTk9WQSAlPiUgDQogIGZpbHRlcighbWlSTkEgJWluJSB0d29fd2F5X2NlbGwgJiBFZmZlY3QgPT0gImNlbGxfbGluZSIpDQpgYGANCg0KIyMjIDEuMy4zIE9uZS1XYXkgQU5PVkENCg0KVG8gZnVydGhlciBpbnZlc3RpZ2F0ZSB0aGUgY2VsbCBsaW5lIGVmZmVjdCBhIG9uZS13YXkgQU5PVkEgd2FzIGNvbmR1Y3RlZCB3aXRoIG1pUk5BIGFuZCBJcnJhZGlhdGlvbiBhcyBncm91cGluZyB2YXJpYWJsZXMuIFRvIGVsaW1pbmF0ZSB0aGUgSXJyYWRpYXRpb24gZWZmZWN0IGFuZCBvbmx5IGNvbXBhcmUgKmJhc2VsaW5lKiBtaVJOQSBleHByZXNzaW9uIGJldHdlZW4gY2VsbCBsaW5lcyB0aGUgcmVzdWx0cyB3ZXJlIGZpbHRlcmVkIGZvciBjb250cm9sIGNlbGxzIG9ubHksIHJlc3VsdGluZyBpbiAzNiBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgbWlSTkFzLg0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQ0KIyAxLXdheSBBTk9WQSANCm9uZV93YXlfQU5PVkEgPC0gZGF0ICU+JQ0KICBncm91cF9ieShtaVJOQSwgSXJyYWRpYXRpb24pICU+JQ0KICAjIHBlcmZvcm0gQU5PVkEgd2l0aCBoY2NtIGNvcnJlY3Rpb24gKHdoaXRlLmFkanVzdCA9IFRSVUUpDQogIGFub3ZhX3Rlc3QobG9nX2V4cCB+IGNlbGxfbGluZSwgd2hpdGUuYWRqdXN0ID0gVFJVRSkgJT4lDQogIGFkanVzdF9wdmFsdWUobWV0aG9kID0gImZkciIpICU+JSANCiAgZmlsdGVyKElycmFkaWF0aW9uID09ICJjb250cm9sIiAmIHAuYWRqIDwgMC4wNSkgJT4lDQogIHNlbGVjdCgtSXJyYWRpYXRpb24pDQpvbmVfd2F5X0FOT1ZBDQpgYGANCg0KKk5PVEU6IHVzaW5nIHRoZSBwb29sZWQgdmFyaWFuY2UgZnJvbSBhIDItd2F5IEFOT1ZBIGluIHRoZSBmb2xsb3dpbmcgMS13YXkgQU5PVkEgeWllbGRzIGEgaGlnaGVyIHN0YXRpc3RpY2FsIHBvd2VyIGJ1dCBpcyBtb3JlIHN1c2NlcHRpYmxlIHRvIHZpb2xhdGlvbnMgZnJvbSB0aGUgaG9tb2dlbmVpdHkgb2YgdmFyaWFuY2UgYXNzdW1wdGlvbnMuIEFuYWxvZ291c2x5IHBvc3QtaG9jIHRlc3RzIHdpdGggcG9vbGVkIHZhcmlhbmNlcyAocG9vbC5zZCA9IFRSVUUpIGFyZSBiZXR0ZXIgaW4gc2l0dWF0aW9ucyB3aGVuIHRoZSBhc3N1bXB0aW9ucyBhcmUgbWV0LCBhdCB0aGUgY29zdCBvZiBiZWluZyBsZXNzIHJvYnVzdCB3aGVuIGFzc3VtcHRpb25zIG5vdCBtZXQuKg0KDQojIyMgMS4zLjQgQ2x1c3RlciBhbmFseXNpcw0KIyMjIyAxLjMuNC4xIFRoZW9yZXRpY2FsIGJhY2tncm91bmQNCg0KIyMjIyMgKkhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nKg0KDQpIaWVyYXJjaGljYWwgY2x1c3RlcmluZyBpcyBhIG1ldGhvZCB0byBncm91cCBkYXRhIGJhc2VkIG9uIHNpbWlsYXJpdHkgaW4gZGF0YSBzdHJ1Y3R1cmUgYW5kIGlzIG1vc3RseSBhc3NvY2lhdGVkIHdpdGggaGVhdG1hcHMgYW5kIGRlbmRyb2dyYW1zIGZvciBkYXRhIHByZXNlbnRhdGlvbi4gRm9yIGdlbmUvbWlSTkEgZXhwcmVzc2lvbiBhbmFseXNpcyBnZW5lcy9taVJOQXMgdHlwaWNhbGx5IHJlcHJlc2VudCByb3dzIGFuZCBkaWZmZXJlbnQgc2FtcGxlcyByZXByZXNlbnQgY29sdW1ucy4gVG8gZmluZCBnZW5lcy9taVJOQSB0aGF0IGFyZSBzaW1pbGFybHkgZXhwcmVzc2VkLCBkaXN0YW5jZXMgYmV0d2VlbiBnZW5lcy9taVJOQXMgYXJlIG1lYXN1cmVkIGUuZy4gdXNpbmcgZXVjbGlkZWFuIGRpc3RhbmNlOiANCg0KJCQNClxiZWdpbnthbGlnbmVkfQ0KZCA9IFxzcXJ0e1xzdW1fe2k9MX1ebiAoZ2VuZTFfe2l9LWdlbmUyX3tpfSleMn0NClxlbmR7YWxpZ25lZH0NCiQkDQoNCldpdGggZ2VuZTF+aX4gYmVpbmcgdGhlIGV4cHJlc3Npb24gb2YgZ2VuZTEgaW4gc2FtcGxlIGkgYW5kIGdlbmUyfml+IGJlaW5nIHRoZSBleHByZXNzaW9uIG9mIGdlbmUyIGluIHNhbXBsZSBpLg0KQW4gZXhhbXBsZSBmb3IgMiBzYW1wbGVzIGFuZCAyIGdlbmVzIGlzIHNob3duIGJlbG93LiBMZXQgZ2VuZSBleHByZXNzaW9uIG9mIGdlbmUxIGJlIDEuNiBpbiBzYW1wbGUxIGFuZCAwLjUgaW4gc2FtcGxlMiBhbmQgZXhwcmVzc2lvbiBvZiBnZW5lMiBiZSAtMC41IGluIHNhbXBsZTEgYW5kIC0xLjkgaW4gc2FtcGxlMjoNCg0KJCQNClxiZWdpbnthbGlnbmVkfQ0KZCAmID0gXHNxcnR7XHN1bV97aT0xfV5uIChnZW5lMV97aX0tZ2VuZTJfe2l9KV4yfSBcXA0KICAmID0gXHNxcnR7KGdlbmUxX3sxfSAtIGdlbmUyX3sxfSleMiArIChnZW5lMV97Mn0gLSBnZW5lMl97Mn0pXjJ9IFxcDQogICYgPSBcc3FydHsoMS42IC0gKC0wLjUpKV4yICsgKDAuNSAtICgtMS45KSleMn0gXFwNCiAgJiA9IFxzcXJ0ezIuMV4yICsgMi40XjJ9IFxcDQogICYgPSAzLjINClxlbmR7YWxpZ25lZH0NCiQkDQoqTm90ZTogZm9yIDIgc2FtcGxlcyB0aGUgZXVjbGlkZWFuIGRpc3RhbmNlIGJldHdlZW4gMiBnZW5lcy9taVJOQXMgaXMgZXF1YWwgdG8gdGhlIHB5dGhhZ29yZWFuIHRoZW9yZW0uKg0KDQpPdGhlciBwb3NzaWJsZSBkaXN0YW5jZSBtZWFzdXJlcyBpbmNsdWRlOiANCiANCiArIHBlYXJzb24gY29ycmVsYXRpb24gKHBhcmFtZXRyaWMpDQogKyBzcGVhcm1hbiBjb3JyZWxhdGlvbiAobm9uLXBhcmFtZXRyaWMpDQogKyBrZW5kYWxsIGNvcnJlbGF0aW9uIChub24tcGFyYW1ldHJpYykNCiArIG1hbmhhdHRhbiBkaXN0YW5jZSAoaW5zdGVhZCBvZiBzdW1taW5nIHVwIHNxdWFyZWQgZGlzdGFuY2VzIGFuZCB0YWtpbmcgdGhlIHNxYXVyZSByb290LCBhYnNvbHV0ZSB2YWx1ZXMgb2YgZGlmZmVyZW5jZSBhcmUgdXNlZCkNCiArIGNhbmJlcnJhIGRpc3RhbmNlDQogKyBiaW5hcnkgZGlzdGFuY2UNCiArIG1pbmtvd3NraSBkaXN0YW5jZQ0KICsgbWF4aW11bSBkaXN0YW5jZQ0KDQpJbiBtb3JlIGNvbXBsZXggZGVzaWducywgZGlzdGFuY2VzIGFyZSBjYWxjdWxhdGVkIGZvciBlYWNoIGdlbmUvbWlSTkEgcGFpciBhbmQgdGhlIHBhaXIgd2l0aCB0aGUgc21hbGxlc3QgZGlzdGFuY2UgaXMgbWVyZ2VkIGludG8gYSBjbHVzdGVyIChjbHVzdGVyMSkuIFN1YnNlcXVlbnRseSBkaXN0YW5jZXMgYXJlIGNhbGN1bGF0ZWQgYWdhaW4gYnV0IHdpdGggdGhlIHByZXZpb3VzbHkgZ2VuZXJhdGVkIGNsdXN0ZXIgYmVpbmcgdHJlYXRlZCBhcyBhIG5ldyBnZW5lL21pUk5BIGVudGl0eS4gSWYgdGhlIHNtYWxsZXN0IGRpc3RhbmNlIGlzIGJldHdlZW4gMiBvdGhlciBnZW5lcy9taVJOYXMsIHRoZXkgYXJlIG1lcmdlZCBpbnRvIGEgbmV3IHNlcGFyYXRlIGNsdXN0ZXIsIGlmIHRoZSBzbWFsbGVzdCBkaXN0YW5jZSBpcyBiZXR3ZWVuIHNvbWUgZ2VuZS9taVJOQSBhbmQgY2x1c3RlcjEsIHRoaXMgZ2VuZSBpcyBjbHVzdGVyZWQgbmV4dCB0byBjbHVzdGVyMS4gVGhpcyBwcm9jZXNzIGlzIHJlcGVhdGVkIHVudGlsIGFsbCBnZW5lcy9taVJOYXMgYXJlIHBhcnQgb2YgYSBjbHVzdGVyLiBUbyB2aXN1YWxpemUgdGhpcyBwcm9jZXNzIGEgZGVuZHJvZ3JhbSBpcyBkcmF3biwgc2hvd2luZyBkaWZmZXJlbnQgYnJhbmNoZXMgdG8gaW5kaWNhdGUgcmVsYXRpb25zaGlwcy4gVGhlIGxlbmd0aCBvZiB0aGUgYnJhbmNoZXMgY29ycmVzcG9uZHMgdG8gdGhlIHRpbWUgd2hlbiB0aGlzIGNsdXN0ZXIgd2FzIGZvcm1lZCwgbWVhbmluZyB0aGUgc2hvcnRlciB0aGUgYnJhbmNoZXMgdGhlIGNsb3NlciB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIGdlbmVzL21pUk5Bcy4gDQoNClRoZXJlIGFyZSBkaWZmZXJlbnQgYXBwcm9hY2hlcyB0byBjbHVzdGVyIHNpbWlsYXIgc2FtcGxlcyB0b2dldGhlciwgdGhlIG1vc3QgcHJvbWluZW50IGJlaW5nLCBhdmVyYWdlIGxpbmthZ2UsIHNpbmdsZSBsaW5rYWdlIGFuZCBjb21wbGV0ZSBsaW5rYWdlLiBJbiBhdmVyYWdlIGxpbmthZ2UgdGhlIGRpc3RhbmNlIG9mIHNpbmdsZSBnZW5lcy9taVJOQXMgdG8gdGhlIGNlbnRyb2lkIG9mIGNsdXN0ZXJzIGlzIGNhbGN1bGF0ZWQgYW5kIHRoZXkgYXJlIG1lcmdlZCBpbnRvIHRoZSBjbHVzdGVyIHdpdGggdGhlIGxlYXN0IGRpc3RhbmNlIHRvIHRoZSBjZW50cm9pZC4gSW4gc2luZ2xlIGxpbmthZ2UgdGhlIGRpc3RhbmNlIGlzIGNhbGN1bGF0ZWQgYmV0d2VlbiBnZW5lcy9taVJOQXMgYW5kIHRoZSBjbG9zZXN0IHBvaW50IGluIGVhY2ggY2x1c3Rlci4gQW5hbG9nb3VzbHksIGluIGNvbXBsZXRlIGxpbmthZ2UsIHRoZSBkaXN0YW5jZSBpcyBjYWxjdWxhdGVkIGJldHdlZW4gZ2VuZXMvbWlSTmFzIGFuZCB0aGUgZnVydGhlc3QgcG9pbnQgaW4gZWFjaCBjbHVzdGVyLiANCg0KRmluYWxseSwgbm90IG9ubHkgZ2VuZXMvbWlSTkFzIGNhbiBiZSBjbHVzdGVyZWQgYnV0IHRoaXMgcHJvY2VzcyBjYW4gYWxzbyBiZSBhcHBsaWVkIHRvIGRpZmZlcmVudCBzYW1wbGVzIHRvIGZpbmQgcmVsYXRlZCBzYW1wbGVzIGJhc2VkIG9uIHRoZSBleHByZXNzaW9uIHBhdHRlcm4uIA0KDQoqTm90ZTogVGhlIGNob2ljZSBvZiBkaXN0YW5jZSBtZWFzdXJlcyBhbmQgY2x1c3RlcmluZyBhbGdvcml0aG1zIGlzIGNvbXBsZXRlbHkgYXJiaXRyYXJ5LCBzbyB0aGUgYmVzdCBtZXRob2QgaXMgY2hvc2VuIGJ5IGxvb2tpbmcgYXQgdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkYXRhIGZvciBlYWNoIHByb2Nlc3MuIEhvd2V2ZXIsIHRoZXJlIGFyZSBzdHVkaWVzIGluZGljYXRpbmcgdGhhdCBkaXN0YW5jZXMgYmV0d2VlbiBnZW5lcy9taVJOQXMgY2FuIHByZWZlcmFibHkgYmUgY2FsY3VsYXRlZCBieSBjb3JyZWxhdGlvbiB3aGVyZWFzIGRpc3RhbmNlcyBiZXR3ZWVuIHNhbXBsZXMgdHlwaWNhbGx5IGFyZSBjYWxjdWxhdGVkIHVzaW5nIGV1Y2xpZGVhbiBkaXN0YW5jZS4gKFB1YmxpY2F0aW9ucyByYXVzc3VjaGVuKSogXA0KXA0KXA0KDQoNCiMjIyMjICpLLW1lYW5zIGNsdXN0ZXJpbmcqDQoNCkstbWVhbnMgaXMgYSBkaWZmZXJlbnQgYXBwcm9hY2ggdG8gY2x1c3RlciBzaW1pbGFyIGRhdGEgYnV0IHdpdGggYSBkaWZmZXJlbnQgbWF0aGVtYXRpY2FsIGFwcHJvYWNoIGFuZCB0aGUgbmVlZCBvZiBzdXBlcnZpc2lvbiBvZiBhIHJlc2VhcmNoZXIsIHdoZXJlYXMgaGllcmFyY2hpY2FsIGNsdXN0ZXJpbmcgdHlwaWNhbGx5IGlzIGFuIHVuc3VwZXJ2aXNlZCBtZXRob2QuIEluIGstbWVhbnMgY2x1c3RlcmluZyBhIG51bWJlciBrIG9mIGRlc2lyZWQgY2x1c3RlcnMgaXMgc3BlY2lmaWVkIHByZXZpb3VzbHkgdG8gdGhlIGFuYWx5c2lzIChtZXRob2RzIHRvIGZpbmQgdGhlIGJlc3QgayBhcmUgZGVzY3JpYmVkIGluIGEgbGF0ZXIgcGFyYWdyYXBoKS4gRm9yIGFuIGV4YW1wbGUgd2l0aCBrPTMgY2x1c3RlcnMsIHRocmVlIHJhbmRvbSBkYXRhIHBvaW50cyBhcmUgY2hvc2VuIGFzIHRoZSBjZW50ZXIgb2YgYSBjbHVzdGVyLiBBZnRlcndhcmRzIGRpc3RhbmNlcyBmcm9tIGVhY2ggcG9pbnQgdG8gdGhlIHRocmVlIHJhbmRvbWx5IGNob3NlbiBjZW50ZXJzIGFyZSBjYWxjdWxhdGVkIGFuZCB0aGUgcG9pbnRzIGFyZSBhc3NpZ25lZCB0byB0aGUgY2xvc2VzdCBjbHVzdGVyLiBJbiB0aGUgZm9sbG93aW5nLCB0aGUgbWVhbiBmb3IgZWFjaCBjbHVzdGVyIGlzIGNhbGN1bGF0ZWQgYW5kIHRoZSBkaXN0YW5jZSBmcm9tIGVhY2ggcG9pbnQgdG8gdGhlIG1lYW4gb2YgZWFjaCBjbHVzdGVyIGlzIGNhbGN1bGF0ZWQuIElmIG5lY2Vzc2FyeSwgcG9pbnRzIGFyZSByZWFzc2lnbmVkIGFuZCB0aGlzIHByb2Nlc3MgaXMgcmVwZWF0ZWQgdW50aWwgdGhlIHNhbXBsZXMgaW4gdGhlIGNsdXN0ZXIgZG8gbm90IGNoYW5nZSBhbnltb3JlLiBUaGlzIGV4cGxhbmF0aW9uIHJlZmVycyB0byBvbmUgaXRlcmF0aW9uIG9mIHRoZSBrLW1lYW5zIGFsZ29yaXRobS4gVGhlIG51bWJlciBvZiBpdGVyYXRpb25zIGNhbiBhbHNvIGJlIHByZXNwZWNpZmllZCwgYW5kIGZvciBlYWNoIGl0ZXJhdGlvbiB0aHJlZSBuZXcgcmFuZG9tIHBvaW50cyBhcmUgY2hvc2VuIGFzIHRoZSBzdGFydGluZyBwb2ludHMgZm9yIHRoZSBjbHVzdGVycy4gRm9yIGVhY2ggaXRlcmF0aW9uIHRoZSBzdW0gb2YgdmFyaWFuY2VzIHdpdGhpbiB0aGUgY2x1c3RlcnMgaXMgY2FsY3VsYXRlZCBhbmQgc3VtbWFyaXplZCBvdmVyIGFsbCBjbHVzdGVycy4gVGhlIGl0ZXJhdGlvbiB3aXRoIHRoZSBsZWFzdCBzdW0gb2YgdmFyaWFuY2VzIGlzIGNob3NlbiBhcyB0aGUgb3B0aW1hbCBjbHVzdGVyaW5nIHJlc3VsdC4gDQoNClRvIGZpbmQgdGhlIG9wdGltYWwgdmFsdWUgb2YgaywgZGlmZmVyZW50IGFwcHJvYWNoZXMgY2FuIGJlIHVzZWQuIFNvbWV0aW1lcyBpdCBpcyBldmlkZW50IGZyb20gYSBwbG90LCBhIHByZXZpb3VzIFBDQSBvciBoaWVyYXJjaGljYWwgY2x1c3RlciBhbmFseXNpcyBvciBvdGhlciBleHBsb3JhdG9yeSBkYXRhIGFuYWx5c2VzIGhvdyBtYW55IGNsdXN0ZXJzIGFyZSBvcHRpbWFsLiBJbiBvdGhlciBjYXNlcyBkaWZmZXJlbnQgdmFsdWVzIGZvciBrIGNhbiBiZSB1c2VkIGluIGEgdHJpYWwgYW5kIGVycm9yIGFwcHJvYWNoIGFuZCB0aGUgcmVkdWN0aW9uIG9mIHZhcmlhbmNlIGNhbiBiZSBwbG90dGVkIGFnYWluc3Qgay4gSW4gdGhpcyAqZWxib3cgcGxvdCogdGhlcmUgaXMgYSBwb2ludCBhZnRlciB3aGljaCB0aGUgcmVkdWN0aW9uIG9mIHZhcmlhbmNlIG9ubHkgY2hhbmdlcyBzbGlnaHRseS4gVGhpcyBwb2ludCBnZW5lcmFsbHkgY29ycmVzcG9uZHMgdG8gdGhlIG9wdGltYWwgay4gDQpcDQpcDQoNCiMjIyMgMS4zLjQuMiBBbmFseXNpcw0KVGhlIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBtaVJOQXMgd2VyZSB1c2VkIGluIGEgY29tYmluZWQgYXBwcm9hY2ggdXNpbmcgc3VwZXJ2aXNlZCBrbWVhbnMgdG8gY2x1c3RlciBjZWxsIGxpbmVzIChjb2x1bW5zKSB3aXRoIGs9MyBhcyBpbmRpY2F0ZWQgYnkgUENBIGFuZCB1bnN1cGVydmlzZWQgaGllcmFjaGljYWwgY2x1c3RlcmluZyB0byBjbHVzdGVyIG1pUk5BcyAocm93cykuIEZ1cnRoZXJtb3JlIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nIHdhcyBhbHNvIGFwcGxpZWQgaW4gdGhlIHN1YmNsdXN0ZXJzIHNwbGl0IGJ5IGttZWFucy4gVGhlIHJlc3VsdHMgd2VyZSB2aXN1YWxpemVkIGluIGEgSGVhdG1hcCB0byByZWR1Y2UgY29tcGxleGl0eSBhbmQgc2hvdyB0aGUgcXVhbnRpdGF0aXZlIHByb3BlcnRpZXMgb2YgZWFjaCBtaVJOQSBhcyBhbiBvdmVydmlldyAoRmlnLiA0KS4gDQoNCg0KYGBge3J9DQojIEhlYXRtYXAgIA0KIyB0cmFuc2Zvcm0gZGF0YSBmb3IgSGVhdG1hcCBmb3JtYXQNCmRhdF9IZWF0bWFwIDwtIGRhdCAlPiUgDQogIGZpbHRlcihJcnJhZGlhdGlvbiA9PSAiY29udHJvbCIgJiBtaVJOQSAlaW4lIG9uZV93YXlfQU5PVkEkbWlSTkEpICU+JQ0KICBzZWxlY3QoLWMoSXJyYWRpYXRpb24sIGxvZ19leHApKSAlPiUNCiAgc3ByZWFkKG1pUk5BLCBleHByZXNzaW9uKSAlPiUNCiAgbXV0YXRlKGNlbGxfbGluZSA9IHN0cl9yZXBsYWNlX2FsbChjZWxsX2xpbmUsICJfIiwiLSIpKQ0KDQojIHNjYWxlIGRhdGEgZm9yIEhlYXRtYXANCmRhdF9zY2FsZWQgPC0gZGF0X0hlYXRtYXAgJT4lIA0KICBjb2x1bW5fdG9fcm93bmFtZXMoIklEIikgJT4lIA0KICBzZWxlY3QoLWNlbGxfbGluZSkgJT4lDQogIHNjYWxlKCkgJT4lDQogIHQoKQ0KDQojIHNldCBJRCBhcyByb3duYW1lcyBzbyBjb2xvcmJhciB3b3JrcyBwcm9wZXJseQ0KZGF0X2NvbG9yYmFyIDwtIGRhdF9IZWF0bWFwICU+JSBzZWxlY3QoYyhJRCwgY2VsbF9saW5lKSkgJT4lIA0KICBjb2x1bW5fdG9fcm93bmFtZXMoIklEIikNCg0KIyBkZWZpbmUgY29sb3JzIGZvciBjb2xvcmJhciB0byBpZGVudGlmeSBjZWxsIGxpbmVzDQpjb2xvcmJhciA8LSBIZWF0bWFwQW5ub3RhdGlvbigNCiAgZGYgPWRhdF9jb2xvcmJhciwNCiAgY29sID0gbGlzdCgNCiAgICBjZWxsX2xpbmUgPSBjKA0KICAgICAgIk1ldC0xIiA9ICIjMDA3M0MyRkYiLA0KICAgICAgIk1ldC00IiA9ICIjRUZDMDAwRkYiLA0KICAgICAgIlNDQy0xMiI9IiM4Njg2ODZGRiIgLA0KICAgICAgIlNDQy0xMyI9IiNDRDUzNENGRiIsDQogICAgICAiU0NMLUlJIj0iIzdBQTZEQ0ZGIikNCiAgICApLA0KICBhbm5vdGF0aW9uX2xlZ2VuZF9wYXJhbSA9IGxpc3QoDQogICAgY2VsbF9saW5lID0gbGlzdChucm93PTEpDQogICAgKQ0KICApDQoNCiMgZGVmaW5lIGNvbG9yIGZvciB0aGUgSGVhdG1hcCBjZWxscw0KY29sX2Z1biA9IGNvbG9yUmFtcDIoYygtMS44LCAwLCAxLjgpLCBjKGMoIiM2RDlFQzEiLCAid2hpdGUiLCAiI0U0NjcyNiIpKSkNCg0KIyBEcmF3IEhlYXRtYXAgDQpIdCA8LSBIZWF0bWFwKA0KICBkYXRfc2NhbGVkLA0KICBjb2w9IGNvbF9mdW4sDQogIHRvcF9hbm5vdGF0aW9uID0gY29sb3JiYXIsDQogIHJvd19zcGxpdCA9IDQsDQogIGNvbHVtbl90aXRsZSA9IGMoIkEiLCAiQiIsICJDIiksDQogIGJvcmRlciA9IFQsDQogICMgc3BsaXQgY2VsbCBsaW5lcyBpbiAzIGNsdXN0ZXJzIGFjY29yZGluZyB0byBQQ0ENCiAgY29sdW1uX2ttID0gMywgDQogICMgcmVwZWF0IGttIHNwbGl0IDEwMCB0aW1lcyB0byBnZXQgYSBzdGFibGUgY2x1c3Rlcg0KICBjb2x1bW5fa21fcmVwZWF0cyA9IDEwMCwgDQogICMgZGVmaW5lIGRpc3RhbmNlIG1ldHJpYyBhbmQgY2x1c3RlcmluZyBhbGdvcml0aG0NCiAgY2x1c3RlcmluZ19tZXRob2Rfcm93ID0gImF2ZXJhZ2UiLCAjIGF2ZXJhZ2UgbGlua2FnZQ0KICBjbHVzdGVyaW5nX21ldGhvZF9jb2x1bW5zID0gImF2ZXJhZ2UiLA0KICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3JvdyA9ICJwZWFyc29uIiwgDQogIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29sdW1uID0gImV1Y2xpZGVhbiIsDQogICMgcGxvdCBjb3NtZXRpY3MgDQogIHJlY3RfZ3AgPSBncGFyKGNvbCA9ICJ3aGl0ZSIsbHR5ID0gMSwgbHdkID0gMSksDQogIHJvd19uYW1lc19ncCA9IGdwYXIoZm9udHNpemUgPSAxMCksDQogIHNob3dfY29sdW1uX25hbWVzID0gRkFMU0UsDQogIGNvbHVtbl9uYW1lc19ncCA9IGdwYXIoZm9udHNpemUgPSAxMCksDQogIGhlYXRtYXBfbGVnZW5kX3BhcmFtID0gbGlzdCgNCiAgICB0aXRsZSA9ICJyb3cgWi1zY29yZSIsDQogICAgYXQgPSBzZXEoLTIsMixieT0xKSwNCiAgICBjb2xvcl9iYXI9ImNvbnRpbnVvdXMiLA0KICAgIHRpdGxlX3Bvc2l0aW9uID0idG9wY2VudGVyIiwNCiAgICBsZWdlbmRfZGlyZWN0aW9uID0gImhvcml6b250YWwiLA0KICAgIGxlZ2VuZF93aWR0aCA9IHVuaXQoNCwgImNtIikNCiAgICApKQ0KDQojIHBsb3QgdGhlIGZpbmFsIGhlYXRtYXAgd2l0aCBhbm5vdGF0aW9uIGFuZCBsZWdlbmQNCmRyYXcoSHQsIGFubm90YXRpb25fbGVnZW5kX3NpZGUgPSAiYm90dG9tIiwgaGVhdG1hcF9sZWdlbmRfc2lkZSA9ICJib3R0b20iKQ0KYGBgDQoNCiFbKipGaWcuIDQ6IEhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nIGFuYWx5c2lzIG9mIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBtaVJOQXMgYmV0d2VlbiB0aGUgZml2ZSBkaWZmZXJlbnQgY2VsbCBsaW5lcy4qKiBLLW1lYW5zIGNsdXN0ZXJpbmcgd2FzIGFwcGxpZWQgd2l0aCBrPTMgc3BsaXRzIGFzIFBDQSBpbmRpY2F0ZWQgMyBkaXN0aW5jdCBjbHVzdGVycyAoTWV0LTEvTWV0LTQsIFNDQy0xMi9TQ0MtMTMgYW5kIFNDTC1JSSkuIFRoZXNlIGNsdXN0ZXJzIGFyZSBhbHNvIHByZXNlbnQgaW4gdGhlIEhlYXRtYXAgZGlzcGxheWVkIGJ5IHRoZSBjb2xvciBjb2RlIGJlbG93IHRoZSBjb2x1bW4gZGVuZHJvZ3JhbS4gT3JhbmdlIHNob3dzIHVwcmVndWxhdGlvbiBvZiBtaVJOQSBleHByZXNzaW9uLCBibHVlIHNob3dzIGRvd25yZWd1bGF0aW9uIG9mIG1pUk5BIGV4cHJlc3Npb24uIENsdXN0ZXJpbmcgbWV0aG9kOiBhdmVyYWdlIGxpbmthZ2UuIERpc3RhbmNlIG1lYXN1cmUgZm9yIG1pUk5BczogcGVhcnNvbiBjb3JyZWxhdGlvbi4gRGlzdGFuY2UgbWVhc3VyZSBmb3IgY2VsbCBsaW5lczogZXVjbGlkZWFuIGRpc3RhbmNlLiBuID0gNC4gKV0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL01CZW5kZXIxOTkyL1BoRC9NYXJjL1Jlc3VsdHMvY2VsbF9saW5lX0hlYXRtYXAucG5nKQ0KDQpUaGUgY29tYmluZWQgY2x1c3RlciBhbmFseXNpcyBzaG93ZWQgYSBjbGVhciBzZXBhcmF0aW9uIG9mIG1pUk5BIGV4cHJlc3Npb24gZGVwZW5kaW5nIG9uIHRoZSBjZWxsIGxpbmUgY29udGV4dCAoQTogU0NDLTEyL1NDQy0xMyxCOiBTQ0wtSUksQzogTWV0LTEvTWV0LTQpLg0KVGhlIG1pUk5BcyB3ZXJlIGNsdXN0ZXJlZCBpbiA0IGdyb3Vwcy4gQ2x1c3RlciAxIHdhcyB1cHJlZ3VsYXRlZCBpbiBjZWxsIGxpbmUgY2x1c3RlciBBIGNvbXBhcmVkIHRvIGNsdXN0ZXIgQiBhbmQgQy4gQ2x1c3RlciAyIHdhcyB1cHJlZ3VsYXRlZCBpbiBjZWxsIGxpbmUgY2x1c3RlciBCIGNvbXBhcmVkIHRvIGNsdXN0ZXIgQSBhbmQgQy4gQ2x1c3RlciA0IHdhcyB1cHJlZ3VsYXRlZCBpbiBjZWxsIGxpbmUgY2x1c3RlciBDIGNvbXBhcmVkIHRvIEEgYW5kIEIuIENsdXN0ZXIgMyBzaG93ZWQgYW4gaW50ZXJtZWRpYXRlIGV4cHJlc3Npb24gb2YgbWlSTkFzIGluIENsdXN0ZXIgQiBhbmQgQyB3aXRoIHRoZSBsb3dlc3QgZXhwcmVzc2lvbiB2YWx1ZXMgb2JzZXJ2ZWQgaW4gQ2x1c3RlciBBLg0KDQpUYWtlbiB0b2dldGhlciB0aGVzZSBmaW5kaW5ncyBpbmRpY2F0ZSBkaXN0aW5jdCBtaVJOQSBjbHVzdGVycyByZXByZXNlbnRpbmcgYSBjZWxsIGxpbmUgc3BlY2lmaWMgZXBpZ2VuZXRpYyBwYXR0ZXJuIGFuZCBwb3NzaWJseSByZWZsZWN0aW5nIGRpZmZlcmVudGlhdGlvbiwgcDUzIHN0YXR1cyBvciBvdGhlciBwaGVub3R5cGVzIGFzc29jaWF0ZWQgd2l0aCB0aGVzZSBwYXR0ZXJucy4gVG8gaW52ZXN0aWdhdGUgdGhlIGJpb2xvZ2ljYWwgZnVuY3Rpb24gb2YgdGhlIG1pUk5BcyBpbiBlYWNoIGNsdXN0ZXIgZ2VuZSBzZXQgZW5yaWNobWVudCBhbmFseXNpcyB3YXMgY29uZHVjdGVkIHRvIGZpbmQgZW5yaWNoZWQgcGF0aHdheXMgdGFyZ2V0ZWQgYnkgdGhlc2UgbWlSTkFzIChzZWN0aW9uIDEuMy41KS4gDQoNCg0KIyMjIDEuMy41IEdlbmUgc2V0IGVucmljaG1lbnQgYW5hbHlzaXMgKEdTRUEpIHdpdGggUkJpb21pckdTDQoNClRvIGlkZW50aWZ5IHRoZSBzdW1tYXJpemVkIGZ1bmN0aW9uIG9mIHRoZSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgbWlSTkFzIGJldHdlZW4gY2VsbCBsaW5lcywgbWlSTkEgY2x1c3RlcnMgb2J0YWluZWQgaW4gMS4zLjQuMiB3ZXJlIGZ1cnRoZXIgaW52ZXN0aWdhdGVkLiBUaHJlZSBkaXN0aW5jdCBjbHVzdGVycyB3ZXJlIHNlbGVjdGVkIC0gbmFtZWx5IGNsdXN0ZXIgMUEgKHJlcHJlc2VudGluZyBtaVJOQXMgb3ZlcmV4cHJlc3NlZCBpbiBjZWxsIGNsdXN0ZXIgMSBjb250YWluaW5nIFNDQzEyIGFuZCBTQ0MxMyksIGNsdXN0ZXIgMkIgKG1pUk5BcyBvdmVyZXhwcmVzc2VkIGluIGNlbGwgbGluZSBjbHVzdGVyIDIgY29udGFpbmluZyBTQ0wtSUkpIGFuZCBjbHVzdGVyIDRDIChtaVJOQXMgb3ZlcmV4cHJlc3NlZCBpbiBjZWxsIGxpbmUgY2x1c3RlciA0IGNvbnRhaW5nIE1ldC0xIGFuZCBNZXQtNCkgLSBhbmQgZGF0YSB3YXMgZXh0cmFjdGVkIGZyb20gdGhlIGhlYXRtYXAgb2JqZWN0Og0KDQpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQ0KIyBleHRyYWN0IGNsdXN0ZXJzIG91dCBvZiBIZWF0bWFwIG9iamVjdA0KSHRfY2x1c3RlcnMgPC0gZXh0cmFjdF9jbHVzdGVycyhkYXRfc2NhbGVkLCBIdCwgc2FtcGxlTmFtZSA9ICJJRCIsIHNhbXBsZUNsdXN0ID0gImNlbGxDbHVzdGVyIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVOYW1lID0gIm1pUk5BIiwgZ2VuZUNsdXN0ID0gIm1pUkNsdXN0ZXIiKQ0KDQojIGNvbnN0cnVjdCBuZXcgZGF0YSBmcmFtZSBjb250YWluaW5nIGNsdXN0ZXIgaW5mb3JtYXRpb24NCmRhdF9jbHVzdGVycyA8LSBsZWZ0X2pvaW4oZmlsdGVyKGRhdCwgSXJyYWRpYXRpb24gPT0gImNvbnRyb2wiKSwgSHRfY2x1c3RlcnMkY2VsbENsdXN0ZXIpICU+JQ0KICBsZWZ0X2pvaW4oSHRfY2x1c3RlcnMkbWlSQ2x1c3RlcikgJT4lIHNlbGVjdCgtYyhJcnJhZGlhdGlvbiwgY2VsbF9saW5lKSkgJT4lDQogIG11dGF0ZShtaVJOQSA9IHN0cl9yZXBsYWNlX2FsbChtaVJOQSwibGV0IiwgImhzYS1sZXQiKSwNCiAgICAgICAgIG1pUk5BID0gc3RyX3JlcGxhY2VfYWxsKG1pUk5BLCJtaXIiLCAiaHNhLW1pUiIpKQ0KYGBgDQoNCkFmdGVyd2FyZHMgZm9sZC1jaGFuZ2VzIGFuZCBwdmFsdWVzIHdlcmUgY2FsY3VsYXRlZCBmb3IgdXByZWd1bGF0ZWQgbWlSTkFzIGluIGVhY2ggY2VsbCBsaW5lIGNsdXN0ZXIgdnMgdGhlIHJlbWFpbmluZyAyIChlLmcuIG1pUk5BcyBpbiBjbHVzdGVyIDFBIHZzIG1pUk5BcyBpbiBjbHVzdGVyIDFCICsgMUMpLg0KDQpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQ0KIyBjcmVhdGUgbGlzdCBmb3IgZWFjaCBtaVJDbHVzdGVyDQpsc19taVJDbHVzdGVyIDwtIHNwbGl0KGRhdF9jbHVzdGVycywgZiA9IGRhdF9jbHVzdGVycyRtaVJDbHVzdGVyKSAgICAgICAgIA0KDQojIGNvbXBhcmUgQ2x1c3RlciAxQSB0byAxQiBhbmQgMUMsIGRyb3AgYXR0cmlidXRlcyAoaW1wb3J0YW50IGZvciB0aGUgcGF0aHdheSBhbmFseXNpcyBhcyBhIGxpc3QgdGhyZXcgYW4gZXJyb3IpIGFuZCBnZW5lcmF0ZSBhIGRhdGEuZnJhbWUNCmNsXzFBIDwtIGFzLmRhdGEuZnJhbWUobGFwcGx5KHN1bW1hcnlfY2x1c3RlcnMobHNfbWlSQ2x1c3RlciwgMSwgIkEiKSwgRlVOPWRyb3BfYXR0cikpDQojIGNvbXBhcmUgQ2x1c3RlcjJCIHRvIDJBIGFuZCAyQywgZHJvcCBhdHRyaWJ1dGVzIGFuZCBnZW5lcmF0ZSBhIGRhdGEuZnJhbWUNCmNsXzJCIDwtIGFzLmRhdGEuZnJhbWUobGFwcGx5KHN1bW1hcnlfY2x1c3RlcnMobHNfbWlSQ2x1c3RlciwgMiwgIkIiKSwgRlVOPWRyb3BfYXR0cikpDQojIGNvbXBhcmUgQ2x1c3RlciA0QyB0byA0QSBhbmQgNEIsIGRyb3AgYXR0cmlidXRlcyBhbmQgZ2VuZXJhdGUgYSBkYXRhLmZyYW1lDQpjbF80QyA8LSBhcy5kYXRhLmZyYW1lKGxhcHBseShzdW1tYXJ5X2NsdXN0ZXJzKGxzX21pUkNsdXN0ZXIsIDQsICJDIiksIEZVTj1kcm9wX2F0dHIpKQ0KYGBgDQoNCg0KVGhlc2UgZGF0YWZyYW1lcyBjb250YWluaW5nIHRoZSBtaVJOQSBuYW1lLCB0aGUgZm9sZC1jaGFuZ2UgYW5kIHB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGNlbGwgbGluZSBjbHVzdGVyIHZzIHRoZSBvdGhlciB0d28gZm9yIGVhY2ggbWlSTkEgd2VyZSB0aGVuIHVzZWQgZm9yIEdTRUEgd2l0aCB0aGUgUiBwYWNrYWdlICpSQmlvbWlyR1MqICBwcm92aWRpbmcgYSBjb21wcmVoZW5zaXZlIHRvb2wgZm9yIHF1YW50aXRhdGl2ZSBpbnZlc3RpZ2F0aW9uIG9mIG1pUk5BLW1STkEgaW50ZXJhY3Rpb25zIChaaGFuZyAyMDE4KS4gU291cmNlcyBmb3IgZ2VuZSBzZXRzIHVzZWQgaW4gdGhpcyBhbmFseXNlcyB3ZXJlIEtFR0cgKEt5b3RvIEVuY3ljbG9wZWRpYSBvZiBHZW5lcyBhbmQgR2Vub21lcykgYW5kIEdPOkJQIChHZW5lIE9udG9sb2d5OiBCaW9sb2dpY2FsIFByb2Nlc3MpIG9idGFpbmVkIGZyb20gaHR0cDovL3d3dy5nc2VhLW1zaWdkYi5vcmcvZ3NlYS9tc2lnZGIvaW5kZXguanNwIGFzICplbnRyZXogSURzKiBzdG9yZWQgaW4gLmdtdCBmaWxlcy4gVGhlIG1ldHJpYyBmb3IgdGhlIEdTRUEgaW4gdGhpcyBwYWNrYWdlIGlzIGxvZ2lzdGljIHJlZ3Jlc3Npb24gd2l0aCBhIG5lZ2F0aXZlIG1vZGVsIGNvZWZmaWNpZW50IHJlbGF0ZWQgdG8gZ2VuZSBzZXRzIGluaGliaXRlZCBieSB0aGUgbWlSTkEgc2V0IHVuZGVyIGludmVzdGlnYXRpb24gYW5kIGEgcG9zaXRpdmUgbW9kZWwgY29lZmZpY2llbnQgYXNzb2NpYXRlZCB3aXRoIGdlbmUgc2V0cyBhY3RpdmF0ZWQgYnkgdGhlIG1pUk5BIHNldC4gDQoNCkJpb2luZm9ybWF0aWMgYXBwcm9hY2hlcyBhcmUgcHJvbmUgdG8gZmFsc2UtcG9zaXRpdmUgcmVzdWx0cyAoR29kYXJkIDIwMTUpIGR1ZSB0byBhbm5vdGF0aW9uIGFuZCByZXNlYXJjaCBiaWFzIGNvbmNlcm5pbmcgbWlSTkFzIGFuZCBwYXRod2F5czogT24gdGhlIG9uZSBoYW5kIGNlcnRhaW4gbWlSTkFzIGFyZSByZXNlYXJjaGVkIG1vcmUgZXh0ZW5zaXZlbHkgbGVhZGluZyB0byBhIGhpZ2hlciBudW1iZXIgb2YgaWRlbnRpZmllZCB0YXJnZXRzLCBvbiB0aGUgb3RoZXIgaGFuZCB0aGVyZSBhcmUgY2VydGFpbiBwYXRod2F5cyAtIG1vc3RseSBhc3NvY2lhdGVkIHdpdGggY2FuY2VyIC0gd2hpY2ggYXJlIGhpZ2hseSByZWxhdGVkIGFuZCB0aGVyZWZvcmUgZW5yaWNoZWQgaW4gbWFueSBzdHVkaWVzIGV2ZW4gdGhvdWdoIGRpZmZlcmVudCBhcHByb2FjaGVzIHdlcmUgdXNlZCBpbiB0aG9zZSBzdHVkaWVzLiBUaHVzLCB0aGUgbmVlZCBmb3IgbmVnYXRpdmUgY29udHJvbHMgaXMgY3J1Y2lhbCB0byBlbGltaW5hdGUgdGhpcyBiaWFzLiANCg0KSW4gdGhpcyBzdHVkeSB0aHJlZSBjbHVzdGVycyBzaG91bGQgYmUgZXhhbWluZWQgd2l0aCBhIHRvdGFsIG9mIDMwIG1pUk5BcyAoY2x1c3RlciAxQTogMTAgbWlSTkFzLCBjbHVzdGVyIDJCOiA2IG1pUk5BcywgY2x1c3RlciA0QzogMTQgbWlSTkFzKSByZXN1bHRpbmcgaW4gYW4gYXZlcmFnZSBudW1iZXIgb2YgMTAgbWlSTkFzIGluIGVhY2ggY2x1c3Rlci4gVGhlcmVmb3JlIDEwIHJhbmRvbSBtYXR1cmUgbWlSTkFzIHdlcmUgY2hvc2VuIG91dCBvZiBhIHRvdGFsIG9mIDI2MzUgbWlSTkFzIG9idGFpbmVkIGZyb20gbWlSQmFzZSAod3d3Lm1pcmJhc2Uub3JnKSBhcyBjb250cm9scy4gVGhlc2UgbWlSTkFzIHdlcmUgYXNzaWduZWQgcmFuZG9tIEZDIGFuZCBwdmFsdWUgcGFpcnMgb3V0IG9mIHRoZSBvcmlnaW5hbCBhbmFseXNpcyBhcyB0aGlzIGlzIHJlcXVpcmVkIGZvciB0aGUgcGVyZm9ybWVkIHF1YW50aXRhdGl2ZSBhbmFseXNpcy4gVGhpcyBwcm9jZXNzIHdhcyByZXBlYXRlZCA1MCB0aW1lcyB0byBlbnN1cmUgYSBzdWZmaWNpZW50bHkgbGFyZ2UgbnVtYmVyIG9mIGNvbnRyb2wgbWlSTkEgc2V0cy4gQXMgdGhpcyBpdGVyYXRpdmUgcHJvY2VzcyBpcyB0aW1lIGNvbnN1bWluZywgb25jZSB0aGUgY29udHJvbCBkYXRhIHdhcyBnZW5lcmF0ZWQgaXQgd2FzIHN0b3JlZCBpbiBhbiAucmRzIG9iamVjdCB0byBiZSBhY2Nlc3NlZCBsYXRlci4gVG8gYXNzZXNzIGJpYXMsIHRoZSBudW1iZXIgb2YgdGltZXMgYSBwYXRod2F5IHdhcyBlbnJpY2hlZCBpbiB0aGVzZSA1MCBjb250cm9sIHNpbXVsYXRpb25zIHdhcyBzdG9yZWQgYW5kIGRpdmlkZWQgYnkgNTAgdG8gb2J0YWluIGFuIGVucmljaG1lbnQgcGVyY2VudGFnZS4gUGF0aHdheXMgdGhhdCB3ZXJlIGVucmljaGVkIGluIG1vcmUgdGhhbiAxMCAlIG9mIGNvbnRyb2xzIHdlcmUgdGhlbiBvbWl0dGVkIGZyb20gdGhlIGFuYWx5c2lzIHRvIHJlZHVjZSBiaWFzLiANClwNClwNCg0KDQojIyMjIDEuMy41LjEgS0VHRyBwYXRod2F5IGFuYWx5c2lzIA0KDQpDYWxjdWxhdGlvbiBvZiBjb250cm9scyBmb3IgS0VHRyBhbmFseXNpczogDQoNCmBgYHtyfQ0KIyBsb2FkIGRhdGEgd2l0aCBtYXR1cmUgbWlSTkFzIGZyb20gbWlSQmFzZQ0KZGF0X21pUkJhc2UgPC0gcmVhZC5jc3YoIkRhdGEvUGF0aHdheSBBbmFseXNpcy9tYXR1cmVfbWlSTkEuY3N2IiwgaGVhZGVyID0gRkFMU0UpICU+JQ0KICBtdXRhdGUobWlSTkEgPSBzdHJfZXh0cmFjdChWMSwgIihoc2EtbWlSfGhzYS1sZXQpLVxcZHsxLDV9KFs6YWxwaGE6XSstXFxkcHxcXHN8LVxcZHB8WzphbHBoYTpdKykiKSkgJT4lIA0KICBuYS5vbWl0KCkNCg0KIyBkYXRhIGZyYW1lIGNvbnRhaW5pbmcgRkMgYW5kIHB2YWx1ZSBvZiB0aGUgb3JpZ2luYWwgZGF0YSB1c2VkIGZvciByYW5kb20gc2FtcGxpbmcgaW4gY29udHJvbHMNCmN0cmxfc3RhdHMgPC0gcmJpbmQoY2xfMUEsIGNsXzJCLCBjbF80QykgJT4lIA0KICBzZWxlY3QoLW1pUk5BKSANCg0KIyBjYWxjdWxhdGUgR1MgZW5yaWNobWVudCBmb3IgNTAgcmFuZG9tIGNvbnRyb2xzIChjb250YWluaW5nIDEwIG1pUk5BcyBlYWNoKQ0KbiA8LSA1MA0KIyBjdHJsX2xpc3RfS0VHRyA8LSBHU19jb250cm9scyhkYXRhPSBjdHJsX3N0YXRzLHJlcCA9IG4sIG1pUmRhdGEgPSBkYXRfbWlSQmFzZSRtaVJOQSwgc2FtcGxlX24gPSAxMCwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgIGdzX2ZpbGUgPSAiYzIuY3Aua2VnZy52Ny4yLmVudHJlei5nbXQiKQ0KDQojIHRvIGZhY2lsaXRhdGUgZG93bnN0cmVhbSBhbmFseXNpcyB0aGUgY3RybF9saXN0IGlzIHNhdmVkIA0KIyBzYXZlUkRTKGN0cmxfbGlzdCwgZmlsZSA9ICJjdHJsX2xpc3QucmRzIikNCmN0cmxfbGlzdF9LRUdHIDwtIHJlYWRSRFMoZmlsZSA9ICJEYXRhL1BhdGh3YXkgQW5hbHlzaXMvY3RybF9saXN0X0tFR0cucmRzIikgIyBmaWxlIGlzIGF2YWlsYWJsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTUJlbmRlcjE5OTIvUGhEL2Jsb2IvTWFyYy9EYXRhL1BhdGh3YXklMjBBbmFseXNpcy9jdHJsX2xpc3RfS0VHRy5yZHMNCg0KIyBjYWxjdWxhdGUgYmlhcyBhbmQgbWVhbiB0YXJnZXRlZCBnZW5lcw0KcmVzX2N0cmxfS0VHRyA8LSBwYXRod2F5X2N0cmxfc3VtbWFyeShjdHJsX2xpc3RfS0VHRywgbj1uKQ0KYGBgDQoNClwNClwNCg0KIyMjIyMgQ2x1c3RlciAxQSANCg0KQ29tcGFyaXNvbiBvZiBtaVJOQXMgdXByZWd1bGNsXzFBX3ByZWRpY3RlZF9taXJuYV9tcm5hX2l3bHNfS0VHR2F0ZWQgaW4gU0NDLTEyL1NDQy0xMyB2cyBTQ0wtSUksIE1ldC0xIGFuZCBNZXQtNC4NCg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCiMgY2FsY3VsYXRpb24gb2YgR1NFQSBmb3IgbWlSTkFzIHVwcmVndWxhdGVkIGluIGNsdXN0ZXIgMUEgDQoNCiMgY29sbGVjdCBtUk5BIHRhcmdldHMgb2YgdGhlIG1pUk5BcyB1cHJlZ3VsYXRlZCBpbiBjbHVzdGVyIDFBDQpyYmlvbWlyZ3NfbXJuYXNjYW5fY3VzdG9tKG9ialRpdGxlID0gImNsXzFBX3ByZWRpY3RlZCIsIG1pciA9IGNsXzFBJG1pUk5BLCBzcCA9ICJoc2EiLCANCiAgcXVlcnlUeXBlID0gInByZWRpY3RlZCIscGFyYWxsZWxDb21wdXRpbmcgPSBUUlVFLGNsdXN0ZXJUeXBlID0gIlBTT0NLIikNCg0KIyBjYWxjdWxhdGUgR1MgYnkgbG9naXN0aWMgcmVncmVzc2lvbg0KcmJpb21pcmdzX2xvZ2lzdGljKG9ialRpdGxlID0gImNsXzFBX3ByZWRpY3RlZF9taXJuYV9tcm5hX2l3bHNfS0VHRyIsbWlybmFfREUgPSBjbF8xQSwgDQogIHZhcl9taXJuYU5hbWUgPSAibWlSTkEiLHZhcl9taXJuYUZDID0gIkZDIix2YXJfbWlybmFQID0gInB2YWx1ZSIsIG1ybmFsaXN0ID0gY2xfMUFfcHJlZGljdGVkX21ybmFfZW50cmV6X2xpc3QsIA0KICBtcm5hX1dlaWdodCA9IE5VTEwsIGdzX2ZpbGUgPSAiRGF0YS9QYXRod2F5IEFuYWx5c2lzL2MyLmNwLmtlZ2cudjcuMi5lbnRyZXouZ210Iiwgb3B0aW1fbWV0aG9kID0gIklXTFMiLCANCiAgcC5hZGogPSAiZmRyIiwgcGFyYWxsZWxDb21wdXRpbmcgPSBGQUxTRSwgY2x1c3RlclR5cGUgPSAiUFNPQ0siKQ0KDQojIHRvdGFsIG51bWJlciBvZiBzaWduaWZpY2FudGx5IGVucmljaGVkIHBhdGh3YXlzDQpzdW0oY2xfMUFfcHJlZGljdGVkX21pcm5hX21ybmFfaXdsc19LRUdHX0dTJGFkai5wLnZhbCA8IDAuMDUpDQoNCiMgcmVtb3ZlIGVucmljaGVkIHBhdGh3YXlzIHdpdGggYSByYW5kb20gZW5yaWNobWVudCBvZiBtb3JlIHRoYW4gMTAgJQ0KYmlhc19LRUdHIDwtIG5hbWVzKHJlc19jdHJsX0tFR0ckYmlhc1tyZXNfY3RybF9LRUdHJGJpYXMgPiAwLjFdKQ0KY2xfMUFfS0VHR19wbG90IDwtIGNsXzFBX3ByZWRpY3RlZF9taXJuYV9tcm5hX2l3bHNfS0VHR19HUyAlPiUgZmlsdGVyKCFHUyAlaW4lIGJpYXNfS0VHRykNCmBgYA0KDQoNCkluIHRvdGFsIDEzICgxMiBhZnRlciBiaWFzIGNvcnJlY3Rpb24pIEtFR0cgcGF0aHdheXMgd2VyZSBzaWduaWZpY2FudGx5IGVucmljaGVkIGluIHRoZSBnZW5lIHNldCB0YXJnZXRlZCBieSB0aGUgMTAgbWlSTkFzIGluIGNsdXN0ZXIgMUEuIE9uZSBwYXRod2F5IChLRUdHX0dsaW9tYSkgd2FzIGV4Y2x1ZGVkIGZyb20gdGhlIGRvd25zdHJlYW0gYW5hbHlzaXMgYXMgaXQgd2FzIGVucmljaGVkIGluIG1vcmUgdGhhbiAxMCAlIG9mIGNvbnRyb2wgc2ltdWxhdGlvbnMgKGFsc28gZm9yIHRoZSBhbmFseXNpcyBpbiBjbHVzdGVyIDJCIGFuZCBjbHVzdGVyIDRDKS4gIA0KDQpgYGB7ciwgZXZhbCA9IEZBTFNFfQ0KI3Bsb3QgcmVzdWx0cyAodm9sY2FubyBwbG90KQ0KcmJpb21pcmdzX3ZvbGNhbm8oZ3NhZGZtID0gY2xfMUFfS0VHR19wbG90LHRvcGdzTGFiZWwgPSBUUlVFLG4gPSAxNSxnc0xhYmVsU2l6ZSA9IDIsDQogIHNpZ0NvbG91ciA9ICJyZWQiLHBsb3RXaWR0aCA9IDI1MCxwbG90SGVpZ2h0ID0gMjIwLHhMYWJlbCA9ICJtb2RlbCBjb2VmZmljaWVudCIpDQojIHBsb3QgZGlzdHJpYnV0aW9uIG9mIGVucmljaGVkIGdlbmUgc2V0cw0KcmJpb21pcmdzX2Jhcihnc2FkZm0gPSBjbF8xQV9LRUdHX3Bsb3Qsc2lnbmlmX29ubHkgPSBGLGdzLm5hbWUgPSBGLA0KICBuID0gImFsbCIseExhYmVsID0gImdlbmUgc2V0IiwgeUxhYmVsID0gIm1vZGVsIGNvZWZmaWNpZW50IiwgcGxvdFdpZHRoID0gMjUwLCBwbG90SGVpZ2h0ID0gMjIwKQ0KIyBwbG90IHRvcCBlbnJpY2hlZCBnZW5lIHNldHMNCnJiaW9taXJnc19iYXIoZ3NhZGZtID0gY2xfMUFfS0VHR19wbG90LHNpZ25pZl9vbmx5ID0gMTUsZ3MubmFtZSA9IFQseExhYmVsID0gIm1vZGVsIGNvZWZmaWNpZW50IiwNCiAgICAgICAgICAgICAgeVR4dFNpemUgPSA3LCBuID0gMTUsIHBsb3RXaWR0aCA9IDI1MCwgcGxvdEhlaWdodCA9IDIyMCkNCmBgYA0KIVsqKkZpZy4gNTogS0VHRyBwYXRod2F5IGFuYWx5c2lzIG9mIGdlbmUgc2V0cyB0YXJnZXRlZCBieSBtaVJOQXMgaW4gY2x1c3RlciAxQS4qKiBWb2xjYW5vIHBsb3QgZGVwaWN0cyB0aGUgc2lnbmlmaWNhbmNlIGFuZCBkaXJlY3Rpb25hbGl0eSBkaXN0cmlidXRpb24gZm9yIHRoZSBLRUdHIHBhdGh3YXkgdGVzdGVkICjiiJJsb2cgcCB2YWx1ZSB2cy4gbW9kZWwgY29lZmZpY2llbnQpLiBSZWQgKHVwcGVyIHF1YWRyYW50cykgcmVwcmVzZW50IHRoZSBzaWduaWZpY2FudGx5IGVucmljaGVkIEtFR0cgcGF0aHdheXMgYW5kIHRoZSBiYXIgZ3JhcGggaW4gdGhlIHZvbGNhbm8gcGxvdCBzaG93cyB0aGUgb3ZlcmFsbCBkaXN0cmlidXRpb24gb2YgbW9kZWwgY29lZmZpY2llbnQuIFRoZSAxMiBzaWduaWZpY2FudGx5IGVucmljaGVkIHBhdGh3YXlzIGFyZSBsYWJlbGVkLiBCYXIgZ3JhcGggb24gdGhlIGxlZnQgc2hvd3MgdGhlc2UgMTIgZW5yaWNoZWQgZ2VuZSBzZXRzIGluIGEgcXVhbnRpdGF0aXZlIHJlcHJlc2VudGF0aW9uLiBUaGUgYmFycyByZXByZXNlbnQgbW9kZWwgY29lZmZpY2llbnQgwrEgc3RhbmRhcmQgZXJyb3IuIE9ubHkgdGhlIGdlbmUgc2V0cyB3aXRoIGFuIEZEUiBhZGp1c3RlZCBwIDwgMC4wNSBhcmUgcGxvdHRlZCBdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9NQmVuZGVyMTk5Mi9QaEQvTWFyYy9SZXN1bHRzL0tFR0dfY2xfMUEucG5nKQ0KDQpJbnRlcnByZXRhdGlvbj8/PyANCg0KXA0KXA0KDQojIyMjIyBDbHVzdGVyIDJCIA0KQ29tcGFyaXNvbiBvZiBtaVJOQXMgdXByZWd1bGF0ZWQgaW4gIFNDTC1JSSB2cy4gU0NDLTEyLCBTQ0MtMTMgTWV0LTEgYW5kIE1ldC00Lg0KDQpgYGB7ciwgZXZhbCA9IEZBTFNFfQ0KIyBjb2xsZWN0IG1STkEgdGFyZ2V0cyBvZiB0aGUgbWlSTkFzIHVwcmVndWxhdGVkIGluIGNsdXN0ZXIgMkINCnJiaW9taXJnc19tcm5hc2Nhbl9jdXN0b20ob2JqVGl0bGUgPSAiY2xfMkJfcHJlZGljdGVkIiwgbWlyID0gY2xfMkIkbWlSTkEsIHNwID0gImhzYSIsIA0KICAgICAgICAgICAgICAgICAgIHF1ZXJ5VHlwZSA9ICJwcmVkaWN0ZWQiLHBhcmFsbGVsQ29tcHV0aW5nID0gVFJVRSxjbHVzdGVyVHlwZSA9ICJQU09DSyIpDQoNCiMgY2FsY3VsYXRlIEdTIGJ5IGxvZ2lzdGljIHJlZ3Jlc3Npb24NCnJiaW9taXJnc19sb2dpc3RpYyhvYmpUaXRsZSA9ICJjbF8yQl9wcmVkaWN0ZWRfbWlybmFfbXJuYV9pd2xzX0tFR0ciLG1pcm5hX0RFID0gY2xfMkIsIA0KICAgICAgICAgICAgICAgICAgIHZhcl9taXJuYU5hbWUgPSAibWlSTkEiLHZhcl9taXJuYUZDID0gIkZDIix2YXJfbWlybmFQID0gInB2YWx1ZSIsIG1ybmFsaXN0ID0gY2xfMkJfcHJlZGljdGVkX21ybmFfZW50cmV6X2xpc3QsIA0KICAgICAgICAgICAgICAgICAgIG1ybmFfV2VpZ2h0ID0gTlVMTCwgZ3NfZmlsZSA9ICJEYXRhL1BhdGh3YXkgQW5hbHlzaXMvYzIuY3Aua2VnZy52Ny4yLmVudHJlei5nbXQiLCBvcHRpbV9tZXRob2QgPSAiSVdMUyIsIA0KICAgICAgICAgICAgICAgICAgIHAuYWRqID0gImZkciIsIHBhcmFsbGVsQ29tcHV0aW5nID0gRkFMU0UsIGNsdXN0ZXJUeXBlID0gIlBTT0NLIikNCg0KIyB0b3RhbCBudW1iZXIgb2Ygc2lnbmlmaWNhbnRseSBlbnJpY2hlZCBwYXRod2F5cw0Kc3VtKGNsXzJCX3ByZWRpY3RlZF9taXJuYV9tcm5hX2l3bHNfS0VHR19HUyRhZGoucC52YWwgPCAwLjA1KQ0KDQojIHJlbW92ZSBlbnJpY2hlZCBwYXRod2F5cyB3aXRoIGEgcmFuZG9tIGVucmljaG1lbnQgb2YgbW9yZSB0aGFuIDEwICUNCmNsXzJCX0tFR0dfcGxvdCA8LSBjbF8yQl9wcmVkaWN0ZWRfbWlybmFfbXJuYV9pd2xzX0tFR0dfR1MgJT4lIGZpbHRlcighR1MgJWluJSBiaWFzX0tFR0cpDQpgYGANCg0KSW4gdG90YWwgMzQgKDMzIGFmdGVyIGJpYXMgY29ycmVjdGlvbikgS0VHRyBwYXRod2F5cyB3ZXJlIHNpZ25pZmljYW50bHkgZW5yaWNoZWQgaW4gY2x1c3RlciAyQi4gDQoNCmBgYHtyLCBldmFsID0gRkFMU0V9DQojcGxvdCByZXN1bHRzICh2b2xjYW5vIHBsb3QpDQpyYmlvbWlyZ3Nfdm9sY2Fubyhnc2FkZm0gPSBjbF8yQl9LRUdHX3Bsb3QsdG9wZ3NMYWJlbCA9IFRSVUUsbiA9IDE1LGdzTGFiZWxTaXplID0gMiwNCiAgICAgICAgICAgICAgICAgIHNpZ0NvbG91ciA9ICJyZWQiLHBsb3RXaWR0aCA9IDI1MCxwbG90SGVpZ2h0ID0gMjIwLHhMYWJlbCA9ICJtb2RlbCBjb2VmZmljaWVudCIpDQoNCiMgcGxvdCBkaXN0cmlidXRpb24gb2YgZW5yaWNoZWQgZ2VuZSBzZXRzDQpyYmlvbWlyZ3NfYmFyKGdzYWRmbSA9IGNsXzJCX0tFR0dfcGxvdCxzaWduaWZfb25seSA9IEYsZ3MubmFtZSA9IEYsDQogICAgICAgICAgICAgIG4gPSAiYWxsIix4TGFiZWwgPSAiZ2VuZSBzZXQiLCB5TGFiZWwgPSAibW9kZWwgY29lZmZpY2llbnQiLCBwbG90V2lkdGggPSAyNTAsIHBsb3RIZWlnaHQgPSAyMjApDQoNCiMgcGxvdCB0b3AgZW5yaWNoZWQgZ2VuZSBzZXRzDQpyYmlvbWlyZ3NfYmFyKGdzYWRmbSA9IGNsXzJCX0tFR0dfcGxvdCxzaWduaWZfb25seSA9IFQsZ3MubmFtZSA9IFQseExhYmVsID0gIm1vZGVsIGNvZWZmaWNpZW50IiwNCiAgICAgICAgICAgICAgeVR4dFNpemUgPSA3LCBuID0gImFsbCIsIHBsb3RXaWR0aCA9IDI1MCwgcGxvdEhlaWdodCA9IDIyMCkNCmBgYA0KIVsqKkZpZy4gNjogS0VHRyBwYXRod2F5IGFuYWx5c2lzIG9mIGdlbmUgc2V0cyB0YXJnZXRlZCBieSBtaVJOQXMgaW4gY2x1c3RlciAyQi4qKiBWb2xjYW5vIHBsb3QgZGVwaWN0cyB0aGUgc2lnbmlmaWNhbmNlIGFuZCBkaXJlY3Rpb25hbGl0eSBkaXN0cmlidXRpb24gZm9yIHRoZSBLRUdHIHBhdGh3YXkgdGVzdGVkICjiiJJsb2cgcCB2YWx1ZSB2cy4gbW9kZWwgY29lZmZpY2llbnQpLiBSZWQgKHVwcGVyIHF1YWRyYW50cykgcmVwcmVzZW50IHRoZSBzaWduaWZpY2FudGx5IGVucmljaGVkIEtFR0cgcGF0aHdheXMgYW5kIHRoZSBiYXIgZ3JhcGggaW4gdGhlIHZvbGNhbm8gcGxvdCBzaG93cyB0aGUgb3ZlcmFsbCBkaXN0cmlidXRpb24gb2YgbW9kZWwgY29lZmZpY2llbnQuIFRoZSB0b3AgMTUgc2lnbmlmaWNhbnRseSBlbnJpY2hlZCBwYXRod2F5cyBhcmUgbGFiZWxlZC4gQmFyIGdyYXBoIG9uIHRoZSBsZWZ0IHNob3dzIGFsbCAzMyBzaWduaWZpY250bHkgZW5yaWNoZWQgZ2VuZSBzZXRzIGluIGEgcXVhbnRpdGF0aXZlIHJlcHJlc2VudGF0aW9uLiBUaGUgYmFycyByZXByZXNlbnQgbW9kZWwgY29lZmZpY2llbnQgwrEgc3RhbmRhcmQgZXJyb3IuIE9ubHkgdGhlIGdlbmUgc2V0cyB3aXRoIGFuIEZEUiBhZGp1c3RlZCBwIDwgMC4wNSBhcmUgcGxvdHRlZCBdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9NQmVuZGVyMTk5Mi9QaEQvTWFyYy9SZXN1bHRzL0tFR0dfY2xfMkIucG5nKQ0KDQpJbnRlcnByZXRhdGlvbj8/PyANCg0KXA0KXA0KDQojIyMjIENsdXN0ZXIgNEMNCkNvbXBhcmlzb24gb2YgbWlSTkFzIHVwcmVndWxhdGVkIGluICBNZXQtMSBhbmQgTWV0LTQgdnMuIFNDQy0xMiwgU0NDLTEzIGFuZCBTQ0wtSUkuDQoNCmBgYHtyLCBldmFsID0gRkFMU0V9DQojIGNvbGxlY3QgbVJOQSB0YXJnZXRzIG9mIHRoZSBtaVJOQXMgdXByZWd1bGF0ZWQgaW4gY2x1c3RlciA0Qw0KcmJpb21pcmdzX21ybmFzY2FuX2N1c3RvbShvYmpUaXRsZSA9ICJjbF80Q19wcmVkaWN0ZWQiLCBtaXIgPSBjbF80QyRtaVJOQSwgc3AgPSAiaHNhIiwgDQogICAgICAgICAgICAgICAgICAgcXVlcnlUeXBlID0gInByZWRpY3RlZCIscGFyYWxsZWxDb21wdXRpbmcgPSBUUlVFLGNsdXN0ZXJUeXBlID0gIlBTT0NLIikNCg0KIyBjYWxjdWxhdGUgR1MgYnkgbG9naXN0aWMgcmVncmVzc2lvbg0KcmJpb21pcmdzX2xvZ2lzdGljKG9ialRpdGxlID0gImNsXzRDX3ByZWRpY3RlZF9taXJuYV9tcm5hX2l3bHNfS0VHRyIsbWlybmFfREUgPSBjbF80QywgDQogICAgICAgICAgICAgICAgICAgdmFyX21pcm5hTmFtZSA9ICJtaVJOQSIsdmFyX21pcm5hRkMgPSAiRkMiLHZhcl9taXJuYVAgPSAicHZhbHVlIiwgbXJuYWxpc3QgPSBjbF80Q19wcmVkaWN0ZWRfbXJuYV9lbnRyZXpfbGlzdCwgDQogICAgICAgICAgICAgICAgICAgbXJuYV9XZWlnaHQgPSBOVUxMLCBnc19maWxlID0gIkRhdGEvUGF0aHdheSBBbmFseXNpcy9jMi5jcC5rZWdnLnY3LjIuZW50cmV6LmdtdCIsIG9wdGltX21ldGhvZCA9ICJJV0xTIiwgDQogICAgICAgICAgICAgICAgICAgcC5hZGogPSAiZmRyIiwgcGFyYWxsZWxDb21wdXRpbmcgPSBGQUxTRSwgY2x1c3RlclR5cGUgPSAiUFNPQ0siKQ0KDQojIHRvdGFsIG51bWJlciBvZiBzaWduaWZpY2FudGx5IGVucmljaGVkIHBhdGh3YXlzDQpzdW0oY2xfNENfcHJlZGljdGVkX21pcm5hX21ybmFfaXdsc19LRUdHX0dTJGFkai5wLnZhbCA8IDAuMDUpDQoNCiMgcmVtb3ZlIGVucmljaGVkIHBhdGh3YXlzIHdpdGggYSByYW5kb20gZW5yaWNobWVudCBvZiBtb3JlIHRoYW4gMTAgJQ0KY2xfNENfS0VHR19wbG90IDwtIGNsXzRDX3ByZWRpY3RlZF9taXJuYV9tcm5hX2l3bHNfS0VHR19HUyAlPiUgZmlsdGVyKCFHUyAlaW4lIGJpYXNfS0VHRykNCmBgYA0KDQpJbiB0b3RhbCAzMiAoMzEgYWZ0ZXIgYmlhcyBjb3JyZWN0aW9uKSBLRUdHIHBhdGh3YXlzIHdlcmUgc2lnbmlmaWNhbnRseSBlbnJpY2hlZCBpbiBjbHVzdGVyIDRDLiANCg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCiNwbG90IHJlc3VsdHMgKHZvbGNhbm8gcGxvdCkNCnJiaW9taXJnc192b2xjYW5vKGdzYWRmbSA9IGNsXzRDX0tFR0dfcGxvdCx0b3Bnc0xhYmVsID0gVFJVRSxuID0gMTUsZ3NMYWJlbFNpemUgPSAyLA0KICAgICAgICAgICAgICAgICAgc2lnQ29sb3VyID0gInJlZCIscGxvdFdpZHRoID0gMjUwLHBsb3RIZWlnaHQgPSAyMjAseExhYmVsID0gIm1vZGVsIGNvZWZmaWNpZW50IikNCg0KIyBwbG90IGRpc3RyaWJ1dGlvbiBvZiBlbnJpY2hlZCBnZW5lIHNldHMNCnJiaW9taXJnc19iYXIoZ3NhZGZtID0gY2xfNENfS0VHR19wbG90LHNpZ25pZl9vbmx5ID0gRixncy5uYW1lID0gRiwNCiAgICAgICAgICAgICAgbiA9ICJhbGwiLHhMYWJlbCA9ICJnZW5lIHNldCIsIHlMYWJlbCA9ICJtb2RlbCBjb2VmZmljaWVudCIsIHBsb3RXaWR0aCA9IDI1MCwgcGxvdEhlaWdodCA9IDIyMCkNCg0KIyBwbG90IHRvcCBlbnJpY2hlZCBnZW5lIHNldHMNCnJiaW9taXJnc19iYXIoZ3NhZGZtID0gY2xfNENfS0VHR19wbG90LHNpZ25pZl9vbmx5ID0gMTUsZ3MubmFtZSA9IFQseExhYmVsID0gIm1vZGVsIGNvZWZmaWNpZW50IiwNCiAgICAgICAgICAgICAgeVR4dFNpemUgPSA3LCBuID0gImFsbCIsIHBsb3RXaWR0aCA9IDI1MCwgcGxvdEhlaWdodCA9IDIyMCkNCmBgYA0KIVsqKkZpZy4gNzogS0VHRyBwYXRod2F5IGFuYWx5c2lzIG9mIGdlbmUgc2V0cyB0YXJnZXRlZCBieSBtaVJOQXMgaW4gY2x1c3RlciA0Qy4qKiBWb2xjYW5vIHBsb3QgZGVwaWN0cyB0aGUgc2lnbmlmaWNhbmNlIGFuZCBkaXJlY3Rpb25hbGl0eSBkaXN0cmlidXRpb24gZm9yIHRoZSBLRUdHIHBhdGh3YXkgdGVzdGVkICjiiJJsb2cgcCB2YWx1ZSB2cy4gbW9kZWwgY29lZmZpY2llbnQpLiBSZWQgKHVwcGVyIHF1YWRyYW50cykgcmVwcmVzZW50IHRoZSBzaWduaWZpY2FudGx5IGVucmljaGVkIEtFR0cgcGF0aHdheXMgYW5kIHRoZSBiYXIgZ3JhcGggaW4gdGhlIHZvbGNhbm8gcGxvdCBzaG93cyB0aGUgb3ZlcmFsbCBkaXN0cmlidXRpb24gb2YgbW9kZWwgY29lZmZpY2llbnQuIFRoZSB0b3AgMTUgc2lnbmlmaWNhbnRseSBlbnJpY2hlZCBwYXRod2F5cyBhcmUgbGFiZWxlZC4gQmFyIGdyYXBoIG9uIHRoZSBsZWZ0IHNob3dzIGFsbCAzMSBzaWduaWZpY250bHkgZW5yaWNoZWQgZ2VuZSBzZXRzIGluIGEgcXVhbnRpdGF0aXZlIHJlcHJlc2VudGF0aW9uLiBUaGUgYmFycyByZXByZXNlbnQgbW9kZWwgY29lZmZpY2llbnQgwrEgc3RhbmRhcmQgZXJyb3IuIE9ubHkgdGhlIGdlbmUgc2V0cyB3aXRoIGFuIEZEUiBhZGp1c3RlZCBwIDwgMC4wNSBhcmUgcGxvdHRlZCBdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9NQmVuZGVyMTk5Mi9QaEQvTWFyYy9SZXN1bHRzL0tFR0dfY2xfNEMucG5nKQ0KDQpJbnRlcnByZXRhdGlvbj8/PyANCg0KXA0KXA0KDQojIyMjIDEuMy41LjIgR086QlAgYW5hbHlzaXMNCg0KQ2FsY3VsYXRpb24gb2YgY29udHJvbHMgZm9yIEdPOkJQIGFuYWx5c2lzOiANCmBgYHtyfQ0KIyBjYWxjdWxhdGUgR1MgZW5yaWNobWVudCBmb3IgNTAgcmFuZG9tIGNvbnRyb2xzIA0KbiA8LSA1MA0KIyBjdHJsX2xpc3RfR09fQlAgPC0gR1NfY29udHJvbHMoZGF0YT0gY3RybF9zdGF0cyxyZXAgPSBuLCBtaVJkYXRhID0gZGF0X21pUkJhc2UkbWlSTkEsIHNhbXBsZV9uID0gMTAsIA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgZ3NfZmlsZSA9ICJjNS5nby5icC52Ny4yLmVudHJlei54bHMiKQ0KDQojIHRvIGZhY2lsaXRhdGUgZG93bnN0cmVhbSBhbmFseXNpcyB0aGUgY3RybF9saXN0IGlzIHNhdmVkIA0KIyBzYXZlUkRTKGN0cmxfbGlzdF9HT19CUCwgZmlsZSA9ICJjdHJsX2xpc3RfR09fQlAucmRzIikNCmN0cmxfbGlzdF9HT19CUDwtIHJlYWRSRFMoZmlsZSA9ICJEYXRhL1BhdGh3YXkgQW5hbHlzaXMvY3RybF9saXN0X0dPX0JQLnJkcyIpICMgZmlsZSBpcyBhdmFpbGFibGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL01CZW5kZXIxOTkyL1BoRC9ibG9iL01hcmMvRGF0YS9QYXRod2F5JTIwQW5hbHlzaXMvY3RybF9saXN0X0dPX0JQLnJkcw0KDQojIGNhbGN1bGF0ZSBiaWFzIGFuZCBtZWFuIHRhcmdldGVkIGdlbmVzDQpyZXNfY3RybF9HT19CUCA8LXBhdGh3YXlfY3RybF9zdW1tYXJ5KGN0cmxfbGlzdF9HT19CUCwgbj1uKQ0KYGBgDQoNClwNClwNCg0KIyMjIyBDbHVzdGVyIDFBIA0KDQpgYGB7ciwgZXZhbCA9IEZBTFNFfQ0KIyBjYWxjdWxhdGUgR1MgYnkgbG9naXN0aWMgcmVncmVzc2lvbg0KcmJpb21pcmdzX2xvZ2lzdGljKG9ialRpdGxlID0gImNsXzFBX3ByZWRpY3RlZF9taXJuYV9tcm5hX2l3bHNfR09fQlAiLG1pcm5hX0RFID0gY2xfMUEsIA0KICB2YXJfbWlybmFOYW1lID0gIm1pUk5BIix2YXJfbWlybmFGQyA9ICJGQyIsdmFyX21pcm5hUCA9ICJwdmFsdWUiLCBtcm5hbGlzdCA9IGNsXzFBX3ByZWRpY3RlZF9tcm5hX2VudHJlel9saXN0LCANCiAgbXJuYV9XZWlnaHQgPSBOVUxMLGdzX2ZpbGUgPSAiRGF0YS9QYXRod2F5IEFuYWx5c2lzL2M1LmdvLmJwLnY3LjIuZW50cmV6LnhscyIsb3B0aW1fbWV0aG9kID0gIklXTFMiLCANCiAgcC5hZGogPSAiZmRyIixwYXJhbGxlbENvbXB1dGluZyA9IEZBTFNFLGNsdXN0ZXJUeXBlID0gIlBTT0NLIikNCg0KIyBudW1iZXIgb2YgZW5yaWNoZWQgR08gdGVybXMNCnN1bShjbF8xQV9wcmVkaWN0ZWRfbWlybmFfbXJuYV9pd2xzX0dPX0JQX0dTJGFkai5wLnZhbCA8IDAuMDUpDQoNCiMgcmVtb3ZlIGVucmljaGVkIHBhdGh3YXlzIHdpdGggYSByYW5kb20gZW5yaWNobWVudCBvZiBtb3JlIHRoYW4gMTAgJSBhbmQgb25seSBrZWVwIHBhdGh3YXlzIHRoYXQgY29udmVyZ2VkDQpiaWFzX0dPX0JQIDwtIG5hbWVzKHJlc19jdHJsX0dPX0JQJGJpYXNbcmVzX2N0cmxfR09fQlAkYmlhcyA+IDAuMV0pDQpjbF8xQV9Hb19CUF9wbG90IDwtIGNsXzFBX3ByZWRpY3RlZF9taXJuYV9tcm5hX2l3bHNfR09fQlBfR1MgJT4lIGZpbHRlcighR1MgJWluJSBiaWFzX0dPX0JQICYgY29udmVyZ2VkID09ICJZIikjIG51bWJlciBvZiBzaWduaWZpY2FudGx5IGVucmljaGVkIHBhdGh3YXlzDQpgYGANCg0KSW4gdG90YWwgNTAxICg0NDIgYWZ0ZXIgYmlhcyBjb3JyZWN0aW9uKSBHTyB0ZXJtcyAoYmlvbG9naWNhbCBwcm9jZXNzKSB3ZXJlIHNpZ25pZmljYW50bHkgZW5yaWNoZWQuIDU5IEdvIHRlcm1zIHdlcmUgcmFuZG9tbHkgZW5yaWNoZWQgaW4gbW9yZSB0aGFuIDEwICUgb2YgY29udHJvbCBzaW11bGF0aW9ucyBhbmQgb21pdHRlZCBmcm9tIHRoZSBhbmFseXNpcyAoYWxzbyBmb3IgY2x1c3RlciAyQiBhbmQgNEMpLg0KDQpgYGB7ciwgZXZhbCA9IEZBTFNFfQ0KI3Bsb3QgcmVzdWx0cyAodm9sY2FubyBwbG90KQ0KcmJpb21pcmdzX3ZvbGNhbm8oZ3NhZGZtID0gY2xfMUFfR09fQlBfcGxvdCx0b3Bnc0xhYmVsID0gVFJVRSxuID0gNSxnc0xhYmVsU2l6ZSA9IDEuOCwNCiAgICAgICAgICAgICAgICAgIHNpZ0NvbG91ciA9ICIjQ0Q1MzRDRkYiLHBsb3RXaWR0aCA9IDI1MCxwbG90SGVpZ2h0ID0gMjIwLHhMYWJlbCA9ICJtb2RlbCBjb2VmZmljaWVudCIpDQoNCiMgcGxvdCBkaXN0cmlidXRpb24gb2YgZW5yaWNoZWQgZ2VuZSBzZXRzDQpyYmlvbWlyZ3NfYmFyKGdzYWRmbSA9IGNsXzFBX0dPX0JQX3Bsb3Qsc2lnbmlmX29ubHkgPSBGLGdzLm5hbWUgPSBGLA0KICAgICAgICAgICAgICBuID0gImFsbCIseExhYmVsID0gImdlbmUgc2V0IiwgeUxhYmVsID0gIm1vZGVsIGNvZWZmaWNpZW50IiwgcGxvdFdpZHRoID0gMjUwLCBwbG90SGVpZ2h0ID0gMjIwKQ0KDQojIHBsb3QgdG9wIGVucmljaGVkIGdlbmUgc2V0cw0KcmJpb21pcmdzX2Jhcihnc2FkZm0gPSBjbF8xQV9HT19CUF9wbG90LHNpZ25pZl9vbmx5ID0gMTUsZ3MubmFtZSA9IFQseExhYmVsID0gIm1vZGVsIGNvZWZmaWNpZW50IiwNCiAgICAgICAgICAgICAgeVR4dFNpemUgPSA3LCBuID0gNTAsIHBsb3RXaWR0aCA9IDI1MCwgcGxvdEhlaWdodCA9IDIyMCkNCmBgYA0KIVsqKkZpZy4gODogR086QlAgYW5hbHlzaXMgb2YgZ2VuZSBzZXRzIHRhcmdldGVkIGJ5IG1pUk5BcyBpbiBjbHVzdGVyIDFBLioqIFZvbGNhbm8gcGxvdCBkZXBpY3RzIHRoZSBzaWduaWZpY2FuY2UgYW5kIGRpcmVjdGlvbmFsaXR5IGRpc3RyaWJ1dGlvbiBmb3IgdGhlIEdPIHRlcm1zICB0ZXN0ZWQgKOKIkmxvZyBwIHZhbHVlIHZzLiBtb2RlbCBjb2VmZmljaWVudCkuIFJlZCAodXBwZXIgcXVhZHJhbnRzKSByZXByZXNlbnQgdGhlIHNpZ25pZmljYW50bHkgZW5yaWNoZWQgR08gdGVybXMgYW5kIHRoZSBiYXIgZ3JhcGggaW4gdGhlIHZvbGNhbm8gcGxvdCBzaG93cyB0aGUgb3ZlcmFsbCBkaXN0cmlidXRpb24gb2YgbW9kZWwgY29lZmZpY2llbnQuIFRoZSB0b3AgNSBzaWduaWZpY2FudGx5IGVucmljaGVkIHBhdGh3YXlzIGFyZSBsYWJlbGVkLiBCYXIgZ3JhcGggb24gdGhlIGxlZnQgc2hvd3MgdGhlIHRvcCA1MCBlbnJpY2hlZCBnZW5lIHNldHMgaW4gYSBxdWFudGl0YXRpdmUgcmVwcmVzZW50YXRpb24uIFRoZSBiYXJzIHJlcHJlc2VudCBtb2RlbCBjb2VmZmljaWVudCDCsSBzdGFuZGFyZCBlcnJvci4gT25seSB0aGUgZ2VuZSBzZXRzIHdpdGggYW4gRkRSIGFkanVzdGVkIHAgPCAwLjA1IGFyZSBwbG90dGVkIF0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL01CZW5kZXIxOTkyL1BoRC9NYXJjL1Jlc3VsdHMvR09fQlBfY2xfMUEucG5nKQ0KDQpcDQpcDQoNCiMjIyMgQ2x1c3RlciAyQg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCiMgY2FsY3VsYXRlIEdTIGJ5IGxvZ2lzdGljIHJlZ3Jlc3Npb24NCnJiaW9taXJnc19sb2dpc3RpYyhvYmpUaXRsZSA9ICJjbF8yQl9wcmVkaWN0ZWRfbWlybmFfbXJuYV9pd2xzX0dPX0JQIixtaXJuYV9ERSA9IGNsXzJCLCANCiAgICAgICAgICAgICAgICAgICB2YXJfbWlybmFOYW1lID0gIm1pUk5BIix2YXJfbWlybmFGQyA9ICJGQyIsdmFyX21pcm5hUCA9ICJwdmFsdWUiLCBtcm5hbGlzdCA9IGNsXzJCX3ByZWRpY3RlZF9tcm5hX2VudHJlel9saXN0LCANCiAgICAgICAgICAgICAgICAgICBtcm5hX1dlaWdodCA9IE5VTEwsZ3NfZmlsZSA9ICJEYXRhL1BhdGh3YXkgQW5hbHlzaXMvYzUuZ28uYnAudjcuMi5lbnRyZXoueGxzIixvcHRpbV9tZXRob2QgPSAiSVdMUyIsIA0KICAgICAgICAgICAgICAgICAgIHAuYWRqID0gImZkciIscGFyYWxsZWxDb21wdXRpbmcgPSBGQUxTRSxjbHVzdGVyVHlwZSA9ICJQU09DSyIpDQoNCiMgbnVtYmVyIG9mIGVucmljaGVkIEdPIHRlcm1zDQpzdW0oY2xfMkJfcHJlZGljdGVkX21pcm5hX21ybmFfaXdsc19HT19CUF9HUyRhZGoucC52YWwgPCAwLjA1KQ0KDQojIHJlbW92ZSBlbnJpY2hlZCBwYXRod2F5cyB3aXRoIGEgcmFuZG9tIGVucmljaG1lbnQgb2YgbW9yZSB0aGFuIDEwICUgYW5kIG9ubHkga2VlcCBwYXRod2F5cyB0aGF0IGNvbnZlcmdlZA0KY2xfMkJfR29fQlBfcGxvdCA8LSBjbF8yQl9wcmVkaWN0ZWRfbWlybmFfbXJuYV9pd2xzX0dPX0JQX0dTICU+JSBmaWx0ZXIoIUdTICVpbiUgYmlhc19HT19CUCAmIGNvbnZlcmdlZCA9PSAiWSIpIyBudW1iZXIgb2Ygc2lnbmlmaWNhbnRseSBlbnJpY2hlZCBwYXRod2F5cw0KDQpgYGANCg0KSW4gdG90YWwgNTI1ICg0NjYgYWZ0ZXIgYmlhcyBjb3JyZWN0aW9uKSBHTyB0ZXJtcyB3ZXJlIGVucmljaGVkIGluIGNsdXN0ZXIgMkIuIA0KDQpgYGB7ciwgZXZhbCA9IEZBTFNFfQ0KI3Bsb3QgcmVzdWx0cyAodm9sY2FubyBwbG90KQ0KcmJpb21pcmdzX3ZvbGNhbm8oZ3NhZGZtID0gY2xfMkJfR09fQlBfcGxvdCx0b3Bnc0xhYmVsID0gVFJVRSxuID0gMTAsZ3NMYWJlbFNpemUgPSAxLjgsDQogICAgICAgICAgICAgICAgICBzaWdDb2xvdXIgPSAiI0NENTM0Q0ZGIixwbG90V2lkdGggPSAyNTAscGxvdEhlaWdodCA9IDIyMCx4TGFiZWwgPSAibW9kZWwgY29lZmZpY2llbnQiKQ0KDQojIHBsb3QgZGlzdHJpYnV0aW9uIG9mIGVucmljaGVkIGdlbmUgc2V0cw0KcmJpb21pcmdzX2Jhcihnc2FkZm0gPSBjbF8yQl9HT19CUF9wbG90LHNpZ25pZl9vbmx5ID0gRixncy5uYW1lID0gRiwNCiAgICAgICAgICAgICAgbiA9ICJhbGwiLHhMYWJlbCA9ICJnZW5lIHNldCIsIHlMYWJlbCA9ICJtb2RlbCBjb2VmZmljaWVudCIsIHBsb3RXaWR0aCA9IDI1MCwgcGxvdEhlaWdodCA9IDIyMCkNCg0KIyBwbG90IHRvcCBlbnJpY2hlZCBnZW5lIHNldHMNCnJiaW9taXJnc19iYXIoZ3NhZGZtID0gY2xfMkJfR09fQlBfcGxvdCxzaWduaWZfb25seSA9IFQsZ3MubmFtZSA9IFQseExhYmVsID0gIm1vZGVsIGNvZWZmaWNpZW50IiwNCiAgICAgICAgICAgICAgeVR4dFNpemUgPSA3LCBuID0gNTAsIHBsb3RXaWR0aCA9IDI1MCwgcGxvdEhlaWdodCA9IDIyMCkNCmBgYA0KIVsqKkZpZy4gOTogR086QlAgYW5hbHlzaXMgb2YgZ2VuZSBzZXRzIHRhcmdldGVkIGJ5IG1pUk5BcyBpbiBjbHVzdGVyIDJCLioqIFZvbGNhbm8gcGxvdCBkZXBpY3RzIHRoZSBzaWduaWZpY2FuY2UgYW5kIGRpcmVjdGlvbmFsaXR5IGRpc3RyaWJ1dGlvbiBmb3IgdGhlIEdPIHRlcm1zICB0ZXN0ZWQgKOKIkmxvZyBwIHZhbHVlIHZzLiBtb2RlbCBjb2VmZmljaWVudCkuIFJlZCAodXBwZXIgcXVhZHJhbnRzKSByZXByZXNlbnQgdGhlIHNpZ25pZmljYW50bHkgZW5yaWNoZWQgR08gdGVybXMgYW5kIHRoZSBiYXIgZ3JhcGggaW4gdGhlIHZvbGNhbm8gcGxvdCBzaG93cyB0aGUgb3ZlcmFsbCBkaXN0cmlidXRpb24gb2YgbW9kZWwgY29lZmZpY2llbnQuIFRoZSB0b3AgMTAgc2lnbmlmaWNhbnRseSBlbnJpY2hlZCBwYXRod2F5cyBhcmUgbGFiZWxlZC4gQmFyIGdyYXBoIG9uIHRoZSBsZWZ0IHNob3dzIHRoZSB0b3AgNTAgZW5yaWNoZWQgZ2VuZSBzZXRzIGluIGEgcXVhbnRpdGF0aXZlIHJlcHJlc2VudGF0aW9uLiBUaGUgYmFycyByZXByZXNlbnQgbW9kZWwgY29lZmZpY2llbnQgwrEgc3RhbmRhcmQgZXJyb3IuIE9ubHkgdGhlIGdlbmUgc2V0cyB3aXRoIGFuIEZEUiBhZGp1c3RlZCBwIDwgMC4wNSBhcmUgcGxvdHRlZC4gXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vTUJlbmRlcjE5OTIvUGhEL01hcmMvUmVzdWx0cy9HT19CUF9jbF8yQi5wbmcpDQoNCg0KXA0KXA0KDQojIyMjIENsdXN0ZXIgNEMNCg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCiMgY2FsY3VsYXRlIEdTIGJ5IGxvZ2lzdGljIHJlZ3Jlc3Npb24NCnJiaW9taXJnc19sb2dpc3RpYyhvYmpUaXRsZSA9ICJjbF80Q19wcmVkaWN0ZWRfbWlybmFfbXJuYV9pd2xzX0dPX0JQIixtaXJuYV9ERSA9IGNsXzRDLCANCiAgICAgICAgICAgICAgICAgICB2YXJfbWlybmFOYW1lID0gIm1pUk5BIix2YXJfbWlybmFGQyA9ICJGQyIsdmFyX21pcm5hUCA9ICJwdmFsdWUiLCBtcm5hbGlzdCA9IGNsXzRDX3ByZWRpY3RlZF9tcm5hX2VudHJlel9saXN0LCANCiAgICAgICAgICAgICAgICAgICBtcm5hX1dlaWdodCA9IE5VTEwsZ3NfZmlsZSA9ICJEYXRhL1BhdGh3YXkgQW5hbHlzaXMvYzUuZ28uYnAudjcuMi5lbnRyZXoueGxzIixvcHRpbV9tZXRob2QgPSAiSVdMUyIsIA0KICAgICAgICAgICAgICAgICAgIHAuYWRqID0gImZkciIscGFyYWxsZWxDb21wdXRpbmcgPSBGQUxTRSxjbHVzdGVyVHlwZSA9ICJQU09DSyIpDQoNCiMgbnVtYmVyIG9mIGVucmljaGVkIEdPIHRlcm1zDQpzdW0oY2xfNENfcHJlZGljdGVkX21pcm5hX21ybmFfaXdsc19HT19CUF9HUyRhZGoucC52YWwgPCAwLjA1KQ0KDQojIHJlbW92ZSBlbnJpY2hlZCBwYXRod2F5cyB3aXRoIGEgcmFuZG9tIGVucmljaG1lbnQgb2YgbW9yZSB0aGFuIDEwICUgYW5kIG9ubHkga2VlcCBwYXRod2F5cyB0aGF0IGNvbnZlcmdlZA0KY2xfNENfR29fQlBfcGxvdCA8LSBjbF80Q19wcmVkaWN0ZWRfbWlybmFfbXJuYV9pd2xzX0dPX0JQX0dTICU+JSBmaWx0ZXIoIUdTICVpbiUgYmlhc19HT19CUCAmIGNvbnZlcmdlZCA9PSAiWSIpIyBudW1iZXIgb2Ygc2lnbmlmaWNhbnRseSBlbnJpY2hlZCBwYXRod2F5cw0KYGBgDQoNCkluIHRvdGFsIDc2NiAoNzA3IGFmdGVyIGJpYXMgY29ycmVjdGlvbikgR08gdGVybXMgd2VyZSBlbnJpY2hlZCBpbiBjbHVzdGVyIDRDLiANCg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCiNwbG90IHJlc3VsdHMgKHZvbGNhbm8gcGxvdCkNCnJiaW9taXJnc192b2xjYW5vKGdzYWRmbSA9IGNsXzRDX0dPX0JQX3Bsb3QsdG9wZ3NMYWJlbCA9IFRSVUUsbiA9IDEwLGdzTGFiZWxTaXplID0gMS44LA0KICAgICAgICAgICAgICAgICAgc2lnQ29sb3VyID0gIiNDRDUzNENGRiIscGxvdFdpZHRoID0gMjUwLHBsb3RIZWlnaHQgPSAyMjAseExhYmVsID0gIm1vZGVsIGNvZWZmaWNpZW50IikNCg0KIyBwbG90IGRpc3RyaWJ1dGlvbiBvZiBlbnJpY2hlZCBnZW5lIHNldHMNCnJiaW9taXJnc19iYXIoZ3NhZGZtID0gY2xfNENfR09fQlBfcGxvdCxzaWduaWZfb25seSA9IEYsZ3MubmFtZSA9IEYsDQogICAgICAgICAgICAgIG4gPSAiYWxsIix4TGFiZWwgPSAiZ2VuZSBzZXQiLCB5TGFiZWwgPSAibW9kZWwgY29lZmZpY2llbnQiLCBwbG90V2lkdGggPSAyNTAsIHBsb3RIZWlnaHQgPSAyMjApDQoNCiMgcGxvdCB0b3AgZW5yaWNoZWQgZ2VuZSBzZXRzDQpyYmlvbWlyZ3NfYmFyKGdzYWRmbSA9IGNsXzRDX0dPX0JQX3Bsb3Qsc2lnbmlmX29ubHkgPSBULGdzLm5hbWUgPSBULHhMYWJlbCA9ICJtb2RlbCBjb2VmZmljaWVudCIsDQogICAgICAgICAgICAgIHlUeHRTaXplID0gNywgbiA9IDUwLCBwbG90V2lkdGggPSAyNTAsIHBsb3RIZWlnaHQgPSAyMjApDQpgYGANCiFbKipGaWcuIDEwOiBHTzpCUCBhbmFseXNpcyBvZiBnZW5lIHNldHMgdGFyZ2V0ZWQgYnkgbWlSTkFzIGluIGNsdXN0ZXIgNEMuKiogVm9sY2FubyBwbG90IGRlcGljdHMgdGhlIHNpZ25pZmljYW5jZSBhbmQgZGlyZWN0aW9uYWxpdHkgZGlzdHJpYnV0aW9uIGZvciB0aGUgR08gdGVybXMgIHRlc3RlZCAo4oiSbG9nIHAgdmFsdWUgdnMuIG1vZGVsIGNvZWZmaWNpZW50KS4gUmVkICh1cHBlciBxdWFkcmFudHMpIHJlcHJlc2VudCB0aGUgc2lnbmlmaWNhbnRseSBlbnJpY2hlZCBHTyB0ZXJtcyBhbmQgdGhlIGJhciBncmFwaCBpbiB0aGUgdm9sY2FubyBwbG90IHNob3dzIHRoZSBvdmVyYWxsIGRpc3RyaWJ1dGlvbiBvZiBtb2RlbCBjb2VmZmljaWVudC4gVGhlIHRvcCAxMCBzaWduaWZpY2FudGx5IGVucmljaGVkIHBhdGh3YXlzIGFyZSBsYWJlbGVkLiBCYXIgZ3JhcGggb24gdGhlIGxlZnQgc2hvd3MgdGhlIHRvcCA1MCBlbnJpY2hlZCBnZW5lIHNldHMgaW4gYSBxdWFudGl0YXRpdmUgcmVwcmVzZW50YXRpb24uIFRoZSBiYXJzIHJlcHJlc2VudCBtb2RlbCBjb2VmZmljaWVudCDCsSBzdGFuZGFyZCBlcnJvci4gT25seSB0aGUgZ2VuZSBzZXRzIHdpdGggYW4gRkRSIGFkanVzdGVkIHAgPCAwLjA1IGFyZSBwbG90dGVkLiBdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9NQmVuZGVyMTk5Mi9QaEQvTWFyYy9SZXN1bHRzL0dPX0JQX2NsXzRDLnBuZykNCg0KXA0KXA0KDQojIyAxLjQgSW52ZXN0aWdhdGlvbiBvZiB0aGUgaXJyYWRpYXRpb24gZWZmZWN0DQoNClRvIGV4YW1pbmUgdGhlIGVmZmVjdCBvZiB0aGUgY2hyb25pYyBJcnJhZGlhdGlvbiBhbmQgaWRlbnRpZnkgaW4gd2hpY2ggY2VsbCBsaW5lcyB0aGVyZSB3YXMgYW4gaXJyYWRpYXRpb24gZWZmZWN0LCBwYWlyd2lzZSBjb21wYXJpc29ucyBiZXR3ZWVuIHRyZWF0ZWQgYW5kIGNvbnRyb2wgc2FtcGxlcyB3ZXJlIGNvbmR1Y3RlZCBmb3IgZWFjaCBjZWxsIGxpbmUgdXNpbmcgdC10ZXN0cy4gVG8gYmFsYW5jZSBUeXBlIEkgYW5kIFR5cGUgSUkgZXJyb3IgcmF0ZSB0aGUgcmVzdWx0cyB3ZXJlIG9ubHkgYWRqdXN0ZWQgZm9yIG11bHRpcGxlIHRlc3RpbmcgYXQgdGhlIEFOT1ZBIChzZWN0aW9uIDEuMy4yKSBsZXZlbCB1c2luZyBmZHItY29ycmVjdGlvbi4gU3Vic2VxdWVudCB0LXRlc3Qgd2VyZSBub3QgYWRqdXN0ZWQgZm9yIG11bHRpcGxlIHRlc3RpbmcgYXMgc3VnZ2VzdGVkIGJ5IEZlaXNlICgyMDAyKSBhbmQgUm90aG1hbiAoMTk5MCkuIENvbmZpcm1hdGlvbiBvZiB0aGUgcmVzdWx0cyB3YXMgcmF0aGVyIGFjaGlldmVkIGJ5IGEgZm9sbG93LXVwIHFQQ1IgKEZpZy4gNykuIA0KDQpEaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiB3YXMgYWNjZXB0ZWQgd2hlbiBmZHIoQU5PVkEpIDwgMC4wNSwgcCh0LXRlc3QpIDwgMC4wNSBhbmQgYSBmb2xkLWNoYW5nZSA+IDEuNSBiZXR3ZWVuIGlycmFkaWF0ZWQgY2VsbHMgYW5kIGNvbnRyb2xzIHdhcyBvYnNlcnZlZC4gQW5hbHlzaXMgb2YgbWlSTkFzIHdhcyBzcGxpdCBpbnRvIHR3byBwYXJ0czogZXhhbWluYXRpb24gb2YgdGhlIGludGVyYWN0aW9uIGVmZmVjdCBhbmQgdGhlIGlycmFkaWF0aW9uIG1haW4gZWZmZWN0LiANCg0KDQojIyMgMS40LjEgSW50ZXJhY3Rpb24gZWZmZWN0IG9mIGNlbGwgbGluZSBhbmQgaXJyYWRpYXRpb24NCg0KQXMgbWVudGlvbmVkIGFib3ZlIDUgbWlSTkFzIHNob3dlZCBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGVmZmVjdCBpbiB0aGUgdHdvLXdheSBBTk9WQSAoc2VjdGlvbiAxLjMuMik6IA0KDQoNCmBgYHtyfQ0KIyBtaVJOQXMgd2l0aCBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGVmZmVjdA0KdHdvX3dheV9BTk9WQSAlPiUgDQogIGZpbHRlcihtaVJOQSAlaW4lIHR3b193YXlfaW50ZXJhY3Rpb24gJiBFZmZlY3QgPT0gImNlbGxfbGluZTpJcnJhZGlhdGlvbiIpIA0KYGBgDQoNCkRhdGEgd2FzIHN1bW1hcml6ZWQgdXNpbmcgZ2VvbWV0cmljIG1lYW4gYW5kIGdlb21ldHJpYyBzZCB0byBzaG93IGRhdGEgaW4gdGhlIG9yaWdpbmFsIHNjYWxlIGJ1dCBzdW1tYXJpemVkIHdpdGggcmVzcGVjdCB0byB0aGUgbG9nLW5vcm1hbCBkaXN0cmlidXRpb24gb2YgdGhlIG1pUk5BIGV4cHJlc3Npb24gdmFsdWVzLiBGb2xkIGNoYW5nZXMgd2VyZSBjYWxjdWxhdGVkIGJ5IGRpdmlkaW5nIHRoZSBnZW9tZXRyaWMgbWVhbiBvZiB0aGUgaXJyYWRpYXRlZCBzYW1wbGVzIGJ5IHRoZSBnZW9tZXRyaWMgbWVhbiBvZiB0aGUgY29udHJvbCBjZWxscyBmb3IgZWFjaCBtaVJOQSBhbmQgY2VsbCBsaW5lLCByZXNwZWN0aXZlbHkuIA0KRm9yIGVhc2llciBjb21wdXRhdGlvbiBhbmQgZ2l2aW5nIHNpbWlsYXIgd2VpZ2h0IHRvIGRvd25yZWd1bGF0aW9uIGFzIHRvIHVwcmVndWxhdGlvbiwgZm9sZCBjaGFuZ2VzIHdlcmUgbG9nMiB0cmFuc2Zvcm1lZCAobG9nMkZDKS5UaGUgYW5hbG9nb3VzIHRocmVzaG9sZCB0byBGQyA+IDEuNSBpcyAgfGxvZzJGQ3wgPiAwLjU4NS4gDQoNCmBgYHtyLCBtZXNzYWdlID0gRkFMU0V9DQojIHN1bW1hcml6ZSBkYXRhIHdpdGggZ2VvbWV0cmljIG1lYW4gYW5kIGdlb21ldHJpYyBzZCBmb3IgZWFjaCBtaVJOQSBpbiBlYWNoIGNlbGwgbGluZSBmb3IgaXJyYWRpYXRlZCBjZWxscyBhbmQgY29udHJvbHMNCmRhdF9zdW1tYXJ5IDwtIGRhdCAlPiUgDQogIG11dGF0ZShleHByZXNzaW9uID0gZXhwcmVzc2lvbiArIDEpICU+JQ0KICBncm91cF9ieShjZWxsX2xpbmUsIElycmFkaWF0aW9uLG1pUk5BKSAlPiUNCiAgc3VtbWFyaXplKGdlb21lYW4gPSBnZW9NZWFuKGV4cHJlc3Npb24sIG5hLnJtID1UKSwgZ2Vvc2QgPSBnZW9TRChleHByZXNzaW9uKSkNCiMgY2FsY3VsYXRlIGZvbGQgY2hhbmdlcyBieSBkaXZpZGluZyB0aGUgZ2VvbWVhbiBleHByZXNzaW9uIHZhbHVlIG9mIGlycmFkaWF0ZWQgY2VsbHMgYnkgZ2VvbWVhbiBleHByZXNzaW9uIHZhbHVlIG9mIA0KIyBjb250cm9sIGNlbGxzIGZvciBlYWNoIGVhY2ggbWlSTkEgaW4gZWFjaCBjZWxsIGxpbmUNCmZvbGRzIDwtICBkYXRfc3VtbWFyeSAlPiUgDQogIGdyb3VwX2J5KGNlbGxfbGluZSwgIG1pUk5BKSAlPiUgDQogIHN1bW1hcml6ZShGQyA9IGdlb21lYW5bSXJyYWRpYXRpb24gPT0gIktBVVZJUiJdL2dlb21lYW5bSXJyYWRpYXRpb24gPT0gImNvbnRyb2wiXSkgJT4lIA0KICBtdXRhdGUobG9nMkZDID0gbG9nMihGQykpICU+JQ0KICBzZXROYW1lcyhjKCJjZWxsX2xpbmUiLCAibWlSTkEiLCJGQyIsICJsb2cyRkMiKSkNCmBgYA0KDQpDb21iaW5pbmcgdGhlIGNyaXRlcmVhIGZvciBkaWZmZXJlbnQgZXhwcmVzc2lvbiBhcyBkZXNjcmliZWQgaW4gc2VjdGlvbiAxLjQsIGZvdXIgbWlSTkFzIHJlbWFpbmVkIChGaWcuIDExKS4NCg0KYGBge3IsIG1lc3NhZ2UgPSBGQUxTRX0NCiMgdC10ZXN0IGZvciB0aGUgaW50ZXJhY3Rpb24gZWZmZWN0DQpwd2NfaW50ZXJhY3Rpb24gPC0gZGF0ICU+JQ0KICBncm91cF9ieShtaVJOQSxjZWxsX2xpbmUpICU+JQ0KIyBzZXQgcG9vbC5zZCA9IEYgdG8gdXNlIGRpZmZlcmVudCB2YXJpYW5jZXMgZm9yIGNhbGN1bGF0aW9ucw0KICBwYWlyd2lzZV90X3Rlc3QobG9nX2V4cH5JcnJhZGlhdGlvbiwgcG9vbC5zZCA9IEYpICU+JQ0KI2ZpbHRlciBvbmx5IG1pUk5BcyB3aXRoIHAgPCAwLjA1IGFuZCBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uIHRlcm0gaW4gdHdvIHdheSBBTk9WQQ0KICBmaWx0ZXIocCA8IDAuMDUgJiBtaVJOQSAlaW4lIHR3b193YXlfaW50ZXJhY3Rpb24pICANCg0KDQojY2FsY3VsYXRlIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGZvciBpbnRlcmFjdGlvbg0KZGlmZl9leHByX2ludGVyYWN0aW9uIDwtIHB3Y19pbnRlcmFjdGlvbiAlPiUNCiAgaW5uZXJfam9pbihmb2xkcykgJT4lDQogIHNlbGVjdChtaVJOQSwgY2VsbF9saW5lLCBwLCBsb2cyRkMpICU+JSANCiAgZmlsdGVyKGFicyhsb2cyRkMpID4gbG9nMigxLjUpKQ0KZGlmZl9leHByX2ludGVyYWN0aW9uDQpgYGANCg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCiMgZnVuY3Rpb24gZXhwYW5kcyBmYWNldCBsaW1pdHMgaW5kaXZpZHVhbGx5IHRvIHBsb3QgZWFjaCBmYWNldCB3aXRoIGFuIGluZGl2aWR1YWwgc2NhbGUNCmZhY2V0X2xpbWl0cyA8LWZ1bmN0aW9uKGRhdGEsIHksIGdyb3VwKXsNCiAgDQogIGRhdCA8LSBkYXRhLnRhYmxlKGRhdGEpDQogIA0KICBkYXRbLHlfbWluIDo9IGV2YWwocGFyc2UodGV4dCA9IHkpKSowLjUsIGJ5ID0gZXZhbChwYXJzZSh0ZXh0ID0gZ3JvdXApKV0NCiAgZGF0Wyx5X21heDo9IGV2YWwocGFyc2UodGV4dCA9IHkpKSoxLjI1LCBieSA9IGV2YWwocGFyc2UodGV4dCA9IGdyb3VwKSldDQogIA0KICBkYXQgPC0gYXNfdGliYmxlKGRhdCkNCiAgcmV0dXJuKGRhdCkNCn0NCg0KIyBhcHBseSBmdW5jdGlvbiBmYWNldF9saW1pdHMgdG8gZ2VuZXJhdGUgaW5kaXZpZHVhbCBmYWNldCBsaW1pdHMgZm9yIHRoZSBwbG90DQpkYXRfcGxvdCA8LSBmYWNldF9saW1pdHMoZGF0X3N1bW1hcnksICJnZW9tZWFuICsgZ2Vvc2QiLCAibWlSTkEiKSAlPiUgDQogIG11dGF0ZShjZWxsX2xpbmUgPSBzdHJfcmVwbGFjZV9hbGwoY2VsbF9saW5lLCAiXyIsIi0iKSkNCg0KIyBkZWZpbmUgbGltaXRzIG9mIGVycm9yYmFyIHRvIG9ubHkgc2hvdyB1cHBlciBlcnJvcmJhcg0KbGltaXRzIDwtIGFlcyh5bWF4ID0gaWZlbHNlKGdlb21lYW4+MCxnZW9tZWFuICsgZ2Vvc2QsZ2VvbWVhbi8yKSwNCiAgICAgICAgICAgICAgeW1pbiA9IGlmZWxzZShnZW9tZWFuPDAsZ2VvbWVhbiAtIGdlb3NkLGdlb21lYW4vMikpDQoNCg0KIyBnZW5lcmF0aW5nIFBsb3QNCmRhdF9wbG90ICU+JSANCiAgIyBvbmx5IHNob3cgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIG1pUk5BcyB3aXRoIGEgc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gdGVybSBpbiB0d28td2F5IEFOT1ZBDQogIGZpbHRlcihtaVJOQSAlaW4lIGRpZmZfZXhwcl9pbnRlcmFjdGlvbiRtaVJOQSkgJT4lDQogIGdncGxvdCgNCiAgICBhZXMoDQogICAgICB4PWNlbGxfbGluZSwNCiAgICAgIHk9Z2VvbWVhbiwNCiAgICAgIGZpbGw9SXJyYWRpYXRpb24NCiAgICAgICkNCiAgICApICsgDQogICMgYWRkIGVycm9yYmFycyB3aXRoIHRoZSBkZWZpbmVkIGxpbWl0cw0KICBnZW9tX2Vycm9yYmFyKA0KICAgIGxpbWl0cywNCiAgICB3aWR0aD0uMiwNCiAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgwLjUpDQogICAgKSArDQogICMgYWRkIGJhcnBsb3RzIHRvIHNob3cgZ2VvbWV0cmljIG1lYW4NCiAgZ2VvbV9iYXIoDQogICAgc3RhdD0iaWRlbnRpdHkiLA0KICAgIGNvbG9yPSJibGFjayIsDQogICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSwNCiAgICB3aWR0aD0gMC41DQogICAgKSArDQogICMgc3BsaXQgcGxvdCBpbnRvIHNlcGFyYXRlIHBsb3QgZm9yIGVhY2ggbWlSTkEgYW5kIGNoYW5nZSB0aGVtZQ0KICBmYWNldF93cmFwKH5taVJOQSxzY2FsZXM9ImZyZWUiKSsgDQogIHRoZW1lX1BoRChheGlzLnRleHQuc2l6ZSA9IDgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLmtleS5zaXplID0gKHVuaXQoMC43LCJsaW5lIikpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iDQogICkgKw0KICAjIGV4dGVuZCBmYWNldHMgYnkgYWRkaW5nIGJsYW5rIGRhdGFwb2ludHMgYXMgZGVmaW5lZCB3aXRoIHRoZSBmdW5jdGlvbiBmYWNldCBsaW1pdHMNCiAgZ2VvbV9ibGFuayhhZXMoeSA9IHlfbWluKSkgKw0KICBnZW9tX2JsYW5rKGFlcyh5ID0geV9tYXgpKSArIA0KICAjIGNoYW5nZSBjb2xvcnMgb2YgdGhlIHBsb3QgZWxlbWVudHMgYW5kIGFkZCB5IGF4aXMgdGl0bGUNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ3JleS5jb2xvcnMoNSxzdGFydD0xLGVuZD0wLjIpKSAgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKw0KICB5bGFiKCJtaVJOQSBleHByZXNzaW9uIChhLnUuKSIpDQpgYGANCg0KDQohWyoqRmlnLiAxMTogbWlSTkEgZXhwcmVzc2lvbiBvZiB0aGUgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIG1pUk5BcyB3aXRoIGFuIGludGVyYWN0aW9uIGVmZmVjdCBvZiBjZWxsIGxpbmUgYW5kIGlycmFkaWF0aW9uIGluIHRoZSB0d28td2F5IEFOT1ZBIChzZWN0aW9uIDEuMy4yKS4qKiBLQVVWSVI6IGNlbGxzIGlycmFkaWF0ZWQgd2l0aCB0aGUgaXJyYWRpYXRpb24gZGV2aWNlIGZvciB0aGUgS0FVVklSIHByb2plY3QuIFJlc3VsdHMgb2YgaW50ZXJhY3Rpb24gdGVybSBpbiB0d28td2F5IEFOT1ZBIGFmdGVyIGZkci1hZGp1c3RtZW50IGFyZSBzaG93biBhYm92ZSB0aGUgcGxvdHMuIFN0dWRlbnQncyB0LXRlc3Qgd2FzIHVzZWQgZm9yIGdyb3VwIGNvbXBhcmlzb25zLiAmIzQyOyYjNDI7JiM0Mjs6IHAgPCAwLjAwMSwgJiM0MjsmIzQyOzogcCA8IDAuMDEsICYjNDI7OiBwIDwgMC4wNS4gZ2VvbWVhbiDCsSBnZW9zZC4gIG4gPSA0LiBdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9NQmVuZGVyMTk5Mi9QaEQvTWFyYy9SZXN1bHRzL21pUk5BX2V4cHJlc3Npb25faW50ZXJhY3Rpb24ucG5nKQ0KDQpOT1RFOiAqKiBBcHBseSBib25mZXJyb25pLWNvcnJlY3Rpb24gZm9yIHRoZSA1IHRlc3RzIHdpdGhpbiBlYWNoIG1pUk5BPyAqKg0KDQpBbGwgNCBtaVJOQXMgd2VyZSB1cHJlZ3VsYXRlZCBpbiBhdCBsZWFzdCBvbmUgY2VsbCBsaW5lIChtaVItMTI2LTNwIGluIFNDQy0xMywgbWlSLTE0NmEtNXAgaW4gU0NMLUlJLCBtaVItMzBhLTNwIGluIFNDQy0xMiBhbmQgU0NMLUlJIGFuZCBtaVItNy01cCBpbiBTQ0wtSUkpLiBBbHRob3VnaCBub3Qgc2lnbmlmaWNhbnRseSBjaGFuZ2VkIHRoZSBzYW1lIHRyZW5kIG9mIHVwcmVndWxhdGlvbiBjYW4gYmUgb2JzZXJ2ZWQgZm9yIG90aGVyIGNlbGwgbGluZXMgYXMgd2VsbCwgd2l0aCBhbiBleGNlcHRpb24gb2YgbWlSLTEyNi0zcCBpbiBNZXQtMSBhbmQgU0NDLTEyLCBtaVItMTQ2YS01cCBpbiBTQ0MtMTIgYW5kIFNDQy0xMyBhbmQgbWlSLTctNXAgaW4gTWV0LTEgYW5kIFNDQy0xMyAod2hpY2ggZXZlbiBzaG93cyBhIGRvd25yZWd1bGF0aW9uIGFmdGVyIGlycmFkaWF0aW9uLCBob3dldmVyIG5vdCBzaWduaWZpY2FudGx5KS4gDQpcDQpcDQpcDQoNCg0KIyMjIyBFeGN1cnNpb246IHQtdGVzdA0KDQpBIHQtdGVzdCBpcyBhIGh5cG90aGVzaXMgdGVzdCB1c2VkIHRvIGNvbXBhcmUgbWVhbnMgb2YgdHdvIHNhbXBsZXMgYSBhbmQgYi4gVGhlIHQtdmFsdWUgZm9yIHNhbXBsZXMgd2l0aCBlcXVhbCB2YXJpYW5jZXMgKFN0dWRlbnQncyB0LXRlc3QpIGlzIGNhbGN1bGF0ZWQgYXM6DQoNCiQkDQpcYmVnaW57YWxpZ25lZH0NCnQgPSBcZnJhY3ttX2EtbV9ifXtcc3FydHtcZnJhY3tTXjJ9e25fYX0gKyBcZnJhY3tTXjJ9e25fYn19fQ0KXGVuZHthbGlnbmVkfQ0KJCQNCg0Kd2l0aCBtfmF+IHRoZSBtZWFuIG9mIHNhbXBsZSBhLCBtfmJ+IHRoZSBtZWFuIG9mIHNhbXBsZSBiLCBufmF+IHRoZSBzYW1wbGUgc2l6ZSBvZiBhLCBufmJ+IHRoZSBzYW1wbGUgc2l6ZSBvZiBiIGFuZCBTXjJeIGJlaW5nIGFuIGVzdGltYXRvciBvZiB0aGUgcG9vbGVkIHZhcmlhbmNlOiANCg0KDQokJA0KXGJlZ2lue2FsaWduZWR9DQpTXjIgPSBcZnJhY3tcc3VtKHgtbV9hKV4yICsgXHN1bSh4LW1fYileMn17bl9hICsgbl9iIC0yfQ0KXGVuZHthbGlnbmVkfQ0KJCQNClRoZSBkZWdyZWVzIG9mIGZyZWVkb20gdXNlZCB0byBjb21wYXJlIHRoZSBjYWxjdWxhdGVkIHQtdmFsdWUgdG8gdGhlIGNyaXRpY2FsIHQtdmFsdWUgaW4gYSB0LXRhYmxlIGFyZToNCg0KJCQNClxiZWdpbnthbGlnbmVkfQ0KZGYgPSBuX3thfSArIG5fe2J9IC0yDQpcZW5ke2FsaWduZWR9DQokJA0KDQpGb3IgdW5lcXVhbCB2YXJpYW5jZXMgKFdlbGNoJ3MgdC10ZXN0KSB0aGUgZm9sbG93aW5nIGZvcm11bGFzIGNhbiBiZSB1c2VkOg0KDQoNCiQkDQpcYmVnaW57YWxpZ25lZH0NCnQgPSBcZnJhY3ttX2EtbV9ifXtcc3FydHtcZnJhY3tTX2FeMn17bl9hfSArIFxmcmFje1NfYl4yfXtuX2J9fX0NClxlbmR7YWxpZ25lZH0NCiQkDQp3aXRoIG1+YX4gdGhlIG1lYW4gb2Ygc2FtcGxlIGEsIG1+Yn4gdGhlIG1lYW4gb2Ygc2FtcGxlIGIsIG5+YX4gdGhlIHNhbXBsZSBzaXplIG9mIGEsIG5+Yn4gdGhlIHNhbXBsZSBzaXplIG9mIGIsIFN+YX4gYmVpbmcgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBhIGFuZCBTfmJ+IGJlaW5nIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgYi4gDQoNClRoZSBkZWdyZWVzIG9mIGZyZWVkb20gaW4gdGhpcyBjYXNlIGFyZSBjYWxjdWxhdGVkIGFzOg0KDQokJA0KXGJlZ2lue2FsaWduZWR9DQpkZiA9IFxmcmFjeyhcZnJhY3tTX2FeMn17bl9hfSAgK1xmcmFje1NfYl4yfXtuX2J9KX17XGZyYWN7U19hXjR9e25fYV4yKG5fYSAtMSl9ICsgXGZyYWN7U19iXjR9e25fYl4yKG5fYiAtMSl9fQ0KXGVuZHthbGlnbmVkfQ0KJCQNCg0KDQojIyMgMS40LjIgTWFpbiBlZmZlY3QgSXJyYWRpYXRpb24NCg0KU3Vic2VxdWVudGx5IHRoZSBpcnJhZGlhdGlvbiBtYWluIGVmZmVjdCBoYXMgYmVlbiBpbnZlc3RpZ2F0ZWQgdG8gYW5hbHl6ZSBtaVJOQXMgd2l0aCBhIGNvbW1vbiBVVi1yZXNwb25zZSBpbiB0aGUgZGlmZmVyZW50IGNlbGwgdHlwZXMgKEZpZy4gMTIpLiANCg0KYGBge3IsIG1lc3NhZ2UgPSBGQUxTRX0NCiMgZmlsdGVyIG1pUk5BcyB3aXRoIGEgc2lnbmlmaWNhbnQgaXJyYWRpYXRpb24gdGVybSBidXQgd2l0aG91dCBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiB0ZXJtDQp0d29fd2F5X2lycmFkaWF0aW9uIDwtIHR3b193YXlfQU5PVkEgJT4lDQogIGZpbHRlcihFZmZlY3QgPT0gIklycmFkaWF0aW9uIiAmIHAuYWRqIDwgMC4wNSAmICFtaVJOQSAlaW4lIHR3b193YXlfaW50ZXJhY3Rpb24pICU+JQ0KICBwdWxsKG1pUk5BKQ0KDQojIHQtdGVzdCBmb3IgdGhlIGlycmFkaWF0aW9uIGVmZmVjdA0KcHdjX2lycmFkaWF0aW9uIDwtIGRhdCU+JQ0KICBncm91cF9ieShtaVJOQSxjZWxsX2xpbmUpICU+JQ0KICBwYWlyd2lzZV90X3Rlc3QobG9nX2V4cH5JcnJhZGlhdGlvbiwgcG9vbC5zZCA9IEYpICU+JSANCiAgZmlsdGVyKHAgPCAwLjA1ICYgbWlSTkEgJWluJSB0d29fd2F5X2lycmFkaWF0aW9uKSANCg0KI2NhbGN1bGF0ZSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBmb3IgSXJyYWRpYXRpb24NCmRpZmZfZXhwcl9pcnJhZGlhdGlvbiA8LSBwd2NfaXJyYWRpYXRpb24gJT4lDQogIGlubmVyX2pvaW4oZm9sZHMpICU+JQ0KICBzZWxlY3QobWlSTkEsIGNlbGxfbGluZSwgcCwgbG9nMkZDKSAlPiUgDQogIGZpbHRlcihhYnMobG9nMkZDKSA+IGxvZzIoMS41KSkNCmRpZmZfZXhwcl9pcnJhZGlhdGlvbg0KYGBgDQoNCg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCmRhdF9wbG90ICU+JSANCiAgIyBvbmx5IHNob3cgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIG1pUk5BcyB3aXRoIGEgc2lnbmlmaWNhbnQgbWFpbiBlZmZlY3QgImlycmFkaWF0aW9uIiB0ZXJtIGluIHR3by13YXkgQU5PVkEgYnV0IHdpdGhvdXQgc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24NCiAgZmlsdGVyKG1pUk5BICVpbiUgZGlmZl9leHByX2lycmFkaWF0aW9uJG1pUk5BKSAlPiUNCiAgZ2dwbG90KA0KICAgIGFlcygNCiAgICAgIHg9Y2VsbF9saW5lLA0KICAgICAgeT1nZW9tZWFuLA0KICAgICAgZmlsbD1JcnJhZGlhdGlvbg0KICAgICkNCiAgKSArIA0KICAjIGFkZCBlcnJvcmJhcnMgd2l0aCB0aGUgZGVmaW5lZCBsaW1pdHMNCiAgZ2VvbV9lcnJvcmJhcigNCiAgICBsaW1pdHMsDQogICAgd2lkdGg9LjIsDQogICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoMC41KQ0KICApICsNCiAgIyBhZGQgYmFycGxvdHMgdG8gc2hvdyBnZW9tZXRyaWMgbWVhbg0KICBnZW9tX2JhcigNCiAgICBzdGF0PSJpZGVudGl0eSIsDQogICAgY29sb3I9ImJsYWNrIiwNCiAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgpLA0KICAgIHdpZHRoPSAwLjUNCiAgKSArDQogICMgc3BsaXQgcGxvdCBpbnRvIHNlcGFyYXRlIHBsb3QgZm9yIGVhY2ggbWlSTkEgYW5kIGNoYW5nZSB0aGVtZQ0KICBmYWNldF93cmFwKH5taVJOQSxzY2FsZXM9ImZyZWUiKSsgDQogIHRoZW1lX1BoRChheGlzLnRleHQuc2l6ZSA9IDgpICsNCiAgdGhlbWUoDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLmtleS5zaXplID0gKHVuaXQoMC43LCJsaW5lIikpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iDQogICkgKw0KICAjIGV4dGVuZCBmYWNldHMgYnkgYWRkaW5nIGJsYW5rIGRhdGFwb2ludHMgYXMgZGVmaW5lZCB3aXRoIHRoZSBmdW5jdGlvbiBmYWNldCBsaW1pdHMNCiAgZ2VvbV9ibGFuayhhZXMoeSA9IHlfbWluKSkgKw0KICBnZW9tX2JsYW5rKGFlcyh5ID0geV9tYXgpKSArIA0KICAjIGNoYW5nZSBjb2xvcnMgb2YgdGhlIHBsb3QgZWxlbWVudHMgYW5kIGFkZCB5IGF4aXMgdGl0bGUNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ3JleS5jb2xvcnMoNSxzdGFydD0xLGVuZD0wLjIpKSAgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKw0KICB5bGFiKCJtaVJOQSBleHByZXNzaW9uIChhLnUuKSIpDQpgYGANCg0KIVsqKkZpZy4gMTI6IG1pUk5BIGV4cHJlc3Npb24gb2YgdGhlIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBtaVJOQXMgd2l0aCBhbiBpcnJhZGlhdGlvbiBtYWluIGVmZmVjdCBpbiB0aGUgdHdvLXdheSBBTk9WQSBidXQgd2l0aG91dCBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiB0ZXJtIChzZWN0aW9uIDEuMy4yKS4qKiBLQVVWSVI6IGNlbGxzIGlycmFkaWF0ZWQgd2l0aCB0aGUgaXJyYWRpYXRpb24gZGV2aWNlIGZvciB0aGUgS0FVVklSIHByb2plY3QuIFJlc3VsdHMgb2YgaXJyYWRpYXRpb24gdGVybSBpbiB0d28td2F5IEFOT1ZBIGFmdGVyIGZkci1hZGp1c3RtZW50IGFyZSBzaG93biBhYm92ZSB0aGUgcGxvdHMuIFN0dWRlbnQncyB0LXRlc3Qgd2FzIHVzZWQgZm9yIGdyb3VwIGNvbXBhcmlzb25zLiAmIzQyOyYjNDI7OiBwIDwgMC4wMSwgJiM0Mjs6IHAgPCAwLjA1LiBnZW9tZWFuIMKxIGdlb3NkLiAgbiA9IDQuIF0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL01CZW5kZXIxOTkyL1BoRC9NYXJjL1Jlc3VsdHMvbWlSTkFfZXhwcmVzc2lvbl9pcnJhZGlhdGlvbi5wbmcpDQoNClNpZ25pZmljYW50IHVwcmVndWxhdGlvbiBjb3VsZCBiZSBkZXRlY3RlZCBmb3IgbWlSLTEzNWItNXAgaW4gU0NDLTEzLCBtaVItMTgzLTVwIGluIFNDQy0xMywgbWlSLTIwMGEtM3AgaW4gU0NDLTEyLCBtaVItMzBkLTVwIGluIFNDQy0xMyBhbmQgbWlSLTQyNC01cCBpbiBTQ0MtMTMuIFRoZSBtaVJOQSBleHByZXNzaW9uIHNob3dzIGEgc2ltaWxhciB0cmVuZCBpbiB0aGUgb3RoZXIgY2VsbCBsaW5lcyBhcyB3ZWxsIHdpdGggYW4gZXhjZXB0aW9uIG9mIG1pUi0xMzViLTVwIGluIE1ldC0xIGFuZCBTQ0wtSUksIG1pUi0yMDBhLTNwIGluIFNDQy0xMyBhbmQgbWlSLTQyNC01cCBpbiBNZXQtMS4gbWlSLTIwNS01cCBpcyB0aGUgb25seSBtaVJOQSBleGhpYml0aW5nIGEgZG93bnJlZ3VsYXRpb24gaW4gYWxsIGNlbGwgbGluZXMsIHdpdGggYSBzaWduaWZpY2FudCBkb3ducmVndWxhdGlvbiBpbiBTQ0wtSUkuIEZ1cnRoZXJtb3JlLCBtaVItMjA1LTVwIHNob3dzIHRoZSBtb3N0IHNpZ25pZmljYW50IGdlbmVyYWwgaXJyYWRpYXRpb24gZWZmZWN0IHdpdGggcCA9IDAuMDAwMjUzIGluIHRoZSB0d28td2F5IEFOT1ZBLiBJbiBzdW1tYXJ5IFVWIGlycmFkaWF0aW9uIHNlZW1zIHRvIGluZHVjZSBtaVJOQSBleHByZXNzaW9uIG1vcmUgb2Z0ZW4gdGhhbiBpbmhpYnRpbmcgbWlSTkEgZXhwcmVzc2lvbiB3aXRoIG1pUi0yMDUtNXAgYmVpbmcgdGhlIG9ubHkgc2lnbmlmaWNhbnRseSBkb3ducmVndWxhdGVkIG1pUk5BIG91dCBvZiB0b3RhbGx5IDEwIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBtaVJOQXMgYmV0d2VlbiB0cmVhdGVkIGFuZCBjb250cm9sIHNhbXBsZXMgKHJlc3VsdHMgZnJvbSBzZWN0aW9uIDEuNC4xIGFuZCAxLjQuMiBjb21iaW5lZCkuIA0KDQpJbnRyaWd1aW5nbHksIHNpZ25pZmljYW50IGlycmFkaWF0aW9uIGVmZmVjdHMgd2VyZSBvbmx5IHByZXNlbnQgaW4gdGhlIHRocmVlIGNlbGwgbGluZXMgU0NDLTEyLCBTQ0MtMTMgYW5kIFNDTC1JSS4gVGhpcyBlZmZlY3QgaGFzIGJlZW4gZnVydGhlciBpbnZlc3RpZ2F0ZWQgaW4gc2VjdGlvbiAxLjUuIA0KDQojIyMgMS40LjMgcVBDUiBWYWxpZGF0aW9uDQoNClRvIHZhbGlkYXRlIHRoZSBmaW5kaW5ncyBvZiBzZWN0aW9uIDEuNC4xIGFuZCBzZWN0aW9uIDEuNC4yIHFQQ1Igd2FzIHBlcmZvcm1lZC4gRm9yIHRoZSBhbmFseXNpcyBmb3VyIGJpb2xvZ2ljYWwgcmVwbGljYXRlcyDigJMgZWFjaCBtZWFzdXJlZCB0d2ljZSB0byByZWR1Y2UgdGVjaG5pY2FsIHZhcmlhYmlsaXR5IOKAkyB3ZXJlIHVzZWQuIFZhbHVlcyBvZiB0ZWNobmljYWwgcmVwbGljYXRlcyB3ZXJlIHN1bW1hcml6ZWQgYnkgYXJpdGhtZXRpYyBtZWFuLiBzbm80NCAoU21hbGwgbnVjbGVvbGFyIFJOQSBTTk9SRDQ0KSwgc25vNDggKFNtYWxsIG51Y2xlb2xhciBSTkEgU05PUkQ0OCkgYW5kIG1pUi0xNi01cCB3ZXJlIHVzZWQgYXMgaG91c2Uta2VlcGluZyBnZW5lcyBmb3Igbm9ybWFsaXNhdGlvbiBhcyBwcmV2aW91c2x5IGRlc2NyaWJlZCAoVmFuZGVzb21wZWxlIDIwMDIpLiBJbiBjb250cmFzdCB0byBMaXZhayBhbmQgU2NobWl0dGdlbiAgzpRDdC0gYW5kIM6UzpRDdC12YWx1ZXMgd2VyZSBjYWxjdWxhdGVkIGFzOg0KDQoNCiQkDQpcYmVnaW57YWxpZ25lZH0NCiDOlEN0ICY9IEN0X3tyZWZ9IC0gQ3Rfe2dvaX1cXA0KIM6UzpRDdCAmPSDOlEN0X3tjdHJsfSAtIM6UQ3Rfe3RydH0NClxlbmR7YWxpZ25lZH0NCiQkDQoNCiANCndpdGggQ3R+cmVmfiByZXByZXNlbnRpbmcgdGhlIEN0IHZhbHVlIG9mIHRoZSByZWZlcmVuY2UgZ2VuZSwgQ3R+Z29pfiByZXByZXNlbnRpbmcgdGhlIEN0IHZhbHVlIG9mIHRoZSBnZW5lIG9mIGludGVyZXN0LCDOlEN0fmN0cmx+IHJlcHJlc2VudGluZyB0aGUgzpRDdC12YWx1ZSBvZiB0aGUgY29udHJvbCBzYW1wbGVzIGFuZCDOlEN0fnRydH4gcmVwcmVzZW50aW5nIHRoZSDOlEN0LXZhbHVlIG9mIHRoZSBpcnJhZGlhdGVkIHNhbXBsZXMuIFRoaXMgd2F5IHBvc2l0aXZlL25lZ2F0aXZlIM6UQ3QtdmFsdWVzIGRpcmVjdGx5IGNvcnJlc3BvbmQgdG8gYSBoaWdoZXIvbG93ZXIgcmVsYXRpdmUgZXhwcmVzc2lvbiBhbmQgcG9zaXRpdmUvbmVnYXRpdmUgzpTOlEN0LXZhbHVlcyBkaXJlY3RseSBjb3JyZXNwb25kIHRvIGEgaGlnaGVyL2xvd2VyIGZvbGQtY2hhbmdlIHdpdGhvdXQgdGhlIG5lZWQgb2YgdGFraW5nIGludmVyc2UgdmFsdWVzLiANCg0KDQpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQ0KIyBzYXZlIHVybA0KdXJsX2ZpbGVfdmFsIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vTUJlbmRlcjE5OTIvUGhEL01hcmMvRGF0YS9QaERfTUJfcVBDUl92YWxpZGF0aW9uX0ZpcmVwbGV4XzIwMjAxMDE1LmNzdiIgDQoNCiMgbG9hZCBkYXRhDQpkYXRfcVBDUiA8LSByZWFkX2Nzdih1cmwodXJsX2ZpbGVfdmFsKSkgJT4lIA0KICByZW5hbWUoTmFtZSA9IFByb2Jlbm5hbWUpICU+JQ0KICAjIGV4dHJhY3QgY2VsbCBsaW5lIG91dCBvZiBJRCBzdHJpbmcNCiAgbXV0YXRlKA0KICAgIGNlbGxfbGluZSA9IHN0cl9yZXBsYWNlX2FsbCguJE5hbWUsIl5cXGQrXyIsIiIpICU+JQ0KICAgICAgc3RyX3JlcGxhY2VfYWxsKCIoX3xcXHMrKShbOmFscGhhOl0rfFxcZCt8KVxcZCpbOmFscGhhOl0qIiwiIikNCiAgICApICU+JQ0KICAjIGV4dHJhY3QgdHJlYXRtZW50IG91dCBvZiBJRCBzdHJpbmcNCiAgbXV0YXRlKA0KICAgIHRyZWF0bWVudCA9IHN0cl9yZXBsYWNlX2FsbCguJE5hbWUsIl5cXGQrX1s6YWxwaGE6XXszfS0oWzphbHBoYTpdezJ9fFxcZCspKF98XFxzKykiLCIiKSAlPiUNCiAgICAgIHN0cl9yZXBsYWNlX2FsbCgiKFxcZCokfF8oWzphbHBoYTpdK3xcXGQrKVxcZCpbOmFscGhhOl0qKSIsIiIpICU+JQ0KICAgICAgc3RyX3JlcGxhY2VfYWxsKCJLMCIsICJjb24iKSwNCiAgICB0cmVhdG1lbnQgPSB0b2xvd2VyKHRyZWF0bWVudCkNCiAgICApICU+JSANCiAgIyBzZXQgZXZlcnl0aGluZyB0byBsb3dlciBjYXNlIGxldHRlcnMgZm9yIHVuaWZvcm1pdHkgd2l0aCB0aGUgcHJldmlvdXMgZGF0YXNldA0KICBtdXRhdGUoZ2VuZV9uYW1lID0gdG9sb3dlcihnZW5lX25hbWUpKQ0KDQojIGxvYWQgbWlSMzBkIGRhdGEgKGNhbGN1bGF0ZWQgc2VwYXJhdGVseSBhcyBtZWFzdXJlZCB3aXRoIGRpZmZlcmVudCBjeWNsZXIgYW5kIG5vcm1hbGl6ZWQgd2l0aCBkaWZmZXJlbnQgSEsgZ2VuZXMpDQp1cmxfbWlSMzAgPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9NQmVuZGVyMTk5Mi9QaEQvTWFyYy9EYXRhL21pUi0zMGQucmRzIiANCmRhdF9taVIzMGQgPC0gcmVhZFJEUyh1cmwodXJsX21pUjMwKSklPiUgDQogIG11dGF0ZShnZW5lX25hbWUgPSB0b2xvd2VyKGdlbmVfbmFtZSkpDQoNCmRhdF9xUENSDQpgYGANCg0KDQpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQ0KIyBjYWxjdWxhdGUgZ2VvTWVhbiBvZiBISyBnZW5lcyBmb3IgZWFjaCBzYW1wbGUNCmRhdF9ISyA8LSBkYXRfcVBDUiAlPiUgDQogIGdyb3VwX2J5KE5hbWUsIGNlbGxfbGluZSkgJT4lDQogIGZpbHRlcihnZW5lX3R5cGUgPT0gIkhLIikgJT4lDQogIG11dGF0ZShnZW9tZWFuX0hLID0gZ2VvTWVhbihtZWFuX2N0LCBuYS5ybT1UKSkgJT4lDQogIGRpc3RpbmN0KGdlb21lYW5fSEspDQoNCiMgY2FsY3VsYXRlIGRDVCB2YWx1ZXMNCmRhdF9kQ1QgPC0gaW5uZXJfam9pbihkYXRfcVBDUiwgZGF0X0hLKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBmaWx0ZXIoZ2VuZV90eXBlICE9ICJISyIpICU+JQ0KICBzZWxlY3QoLWdlbmVfdHlwZSkgJT4lDQogIG11dGF0ZShkQ1QgPSBnZW9tZWFuX0hLIC0gbWVhbl9jdCkNCg0KIyMgY2FsY3VsYXRlIGRkQ1QNCmRkQ1QgPC0gZGF0X2RDVCAlPiUgDQogIGdyb3VwX2J5KGdlbmVfbmFtZSxjZWxsX2xpbmUpICU+JSANCiAgZmlsdGVyKHRyZWF0bWVudCA9PSAiY29uIikgJT4lDQogIHN1bW1hcml6ZShjdHJsX2RDVCA9IG1lYW4oZENULCBuYS5ybSA9IFQpKSAlPiUNCiAgaW5uZXJfam9pbihkYXRfZENUICU+JSANCiAgZmlsdGVyKHRyZWF0bWVudCAhPSAiY29uIikpICU+JQ0KICBtdXRhdGUoZGRDVCA9IGRDVCAtIGN0cmxfZENUKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBzZWxlY3QoLWMoTWVzc3VuZ18xLCBNZXNzdW5nXzIpKSAlPiUNCiAgIyBjb21iaW5lIHdpdGggcHJldmlvdXMgcmVzdWx0cyBvZiBtaVItMzBkDQogIGFkZF9yb3coZGF0X21pUjMwZCkgJT4lIA0KICAjIHJlbmFtZSBjb2x1bW4gdG8gIm1pUk5BIiBmb3Igc3Vic2VxdWVudCBhbmFseXNpcw0KICByZW5hbWUobWlSTkEgPSBnZW5lX25hbWUpIA0KYGBgDQoNCs6UzpRDdC12YWx1ZXMgd2VyZSB0ZXN0ZWQgZm9yIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGZyb20gMCB3aXRoIGEgb25lLXNhbXBsZSB0LXRlc3QgdnMuIDAgYW5kIGNvbXBhcmVkIHRvIHRoZSBGaXJlcGxleCByZXN1bHRzIChGaWcuIDExICYgRmlnLiAxMikuDQoNCmBgYHtyfQ0KIyBvbmUtc2lkZWQgdC10ZXN0IHZzIG51bGwNCmRkQ1QgJT4lIGdyb3VwX2J5KGNlbGxfbGluZSxtaVJOQSkgJT4lIA0KICB0X3Rlc3QoZGRDVH4gMSwgbXUgPSAwKSAlPiUgDQogIGZpbHRlcihwIDw9IDAuMDUpICU+JSANCiAgYXJyYW5nZShtaVJOQSkNCmBgYA0KDQpgYGB7ciwgZXZhbCA9IEZBTFNFfQ0KIyBleHRyYWN0IGZvbGQgY2hhbmdlcyBmb3IgZWFjaCBtaVJOQSBhbmQgY2VsbCBsaW5lIGZyb20gRmlyZXBsZXggYW5hbHlzaXMNCmxvZ0ZDX2ZpcmVwbGV4IDwtIGZvbGRzICU+JQ0KICBmaWx0ZXIobWlSTkEgJWluJSBjKGRkQ1QkbWlSTkEsICJtaXItMzBkLTVwIikpICU+JQ0KICBzZWxlY3QoLUZDKSAlPiUNCiAgbXV0YXRlKGNlbGxfbGluZSA9IHN0cl9yZXBsYWNlX2FsbChjZWxsX2xpbmUsICJfIiwiLSIpKSAlPiUNCiAgc2V0TmFtZXMoYygiY2VsbF9saW5lIiwibWlSTkEiLCAibG9nRkNfRmlyZXBsZXgiKSkgDQoNCiMgam9pbiByZXN1bHRzIGZyb20gcVBDUiBhbmQgRmlyZXBsZXggYW5hbHlzaXMNCmRhdF9wbG90IDwtIGRkQ1QgJT4lDQogIGxlZnRfam9pbihsb2dGQ19maXJlcGxleCkgJT4lDQogIGZpbHRlcighaXMubmEoZGRDVCkpICU+JQ0KICBtdXRhdGUobWlSTkEgPSBmYWN0b3IobWlSTkEsIGxldmVscyA9IG1peGVkc29ydCh1bmlxdWUoLiRtaVJOQSksIGRlY3JlYXNpbmcgPSBUKSkpDQoNCiMgZGVmaW5lIGNvbG9yIHNlcXVlbmNlIGZvciB0aGUgcGxvdA0KY29scyA8LSBjKCIjRTJFMkUyIiwgIiNEQ0RDREMiICwiI0QxRDFEMSIsICIjQzJDMkMyIiwgIiNCMUIxQjEiLCAiIzlFOUU5RSIsICIjOEE4QThBIiAsIiM3NDc0NzQiICwiIzVFNUU1RSIgLCIjNDc0NzQ3IikNCg0KIyBwbG90IGVycm9yYmFycw0KZGF0X3Bsb3QgJT4lIA0KICBnZ3Bsb3QoYWVzKGNlbGxfbGluZSxkZENULGZpbGwgPSBjZWxsX2xpbmUpKSArDQogIHN0YXRfYm94cGxvdCgNCiAgICBnZW9tID0nZXJyb3JiYXInLHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC40OCksDQogICAgc2l6ZT0wLjUsDQogICAgd2lkdGggPSAwLjINCiAgKSArDQogICMgYWRkIGJveHBsb3Qgb24gdG9wIHRoZSBlcnJvcmJhcnMNCiAgZ2VvbV9ib3hwbG90KA0KICAgIGNvbG9yID0gImJsYWNrIiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjQ4KSwgDQogICAgbWFwcGluZyA9IGFlcyh4ID0gY2VsbF9saW5lLHkgPWRkQ1QpLA0KICAgIHdpZHRoPTAuNA0KICApICsNCiAgIyBwbG90IHBvaW50cyBzaG93aW5nIHRoZSBtZWFuIG9mIHRoZSBGaXJlcGxleCByZXN1bHRzDQogIGdlb21fcG9pbnQoYWVzKGNlbGxfbGluZSxsb2dGQ19GaXJlcGxleCksIGZpbGwgPSAicmVkIiwgc2hhcGUgPSAyMykgKw0KICBmYWNldF93cmFwKH5taVJOQSwgc2NhbGVzID0gImZyZWUiKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGx0eSA9IDMpICsNCiAgIyBjaGFuZ2UgdGhlbWUNCiAgdGhlbWVfbWluaW1hbCgpICsgDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLA0KICAgIGF4aXMubGluZS55LmxlZnQgICA9IGVsZW1lbnRfbGluZShjb2xvciA9ICdibGFjaycpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfbGluZSgpLCANCiAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpDQogICAgKSAgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtMi4yLDIuMiksYnJlYWtzID0gc2VxKC0yLDIsIDAuNSkpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHNbc2VxKDIsMTAsMildLCBuYW1lID0gImNlbGwgbGluZSIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sc1tzZXEoMiwxMCwyKV0sIG5hbWUgPSAiY2VsbCBsaW5lIikgKw0KICB5bGFiKCJsb2cyLUZDIikgDQoNCmBgYA0KIVsqKkZpZy4gMTM6IHFQQ1IgdmFsaWRhdGlvbiBvZiBGaXJlcGxleCByZXN1bHRzIChGaWcgMTEuICYgRmlnLjEyKS4qKiBEYXRhIHdlcmUgbm9ybWFsaXplZCB0byB0aGUgZ2VvbWV0cmljIG1lYW4gb2YgbWlSLTE2LCBzbm80NCBhbmQgc25vNDggZXhwcmVzc2lvbi4gU2hvd24gYXJlIGxvZzJGQyBvZiBpcnJhZGlhdGVkIHNhbXBsZXMgaW4gcmVsYXRpb24gdG8gY29udHJvbHMuIE9uZSBzYW1wbGUgdC10ZXN0IHdhcyB1c2VkIGZvciBjb21wYXJpc29uIG9mIGxvZzJGQyB2ZXJzdXMgMC4gUmVkIHNxdWFyZXMgc2hvdyB0aGUgbWVhbiBsb2cyRkMgb2YgaXJyYWRpYXRlZCB2cy4gY29udHJvbCBzYW1wbGVzIGluIHRoZSBGaXJlcGxleCBhbmFseXNpcy4gRm9yIHJlYWRhYmlsaXR5LCBtaVJOQSBleHByZXNzaW9uIHdpdGggfGxvZzJGQ3wgPiAyIGluIHRoZSBGaXJlcGxleCBhbmFseXNpcyBpcyBpbmRpY2F0ZWQgYnkgYXJyb3dzLiAgJiM0MjsmIzQyOzogcCA8IDAuMDEsICYjNDI7OiBwIDwgMC4wNS4gbiA9IDQuIF0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL01CZW5kZXIxOTkyL1BoRC9NYXJjL1Jlc3VsdHMvbWlSTkFfZXhwcmVzc2lvbl9xUENSX3ZhbGlkYXRpb24ucG5nKQ0KDQpHZW5lcmFsbHkgdGhlIHFQQ1IgcmVzdWx0cyB2YWxpZGF0ZSB0aGUgRmlyZXBsZXggcmVzdWx0cyBhcyBpbmRpY2F0ZWQgYnkgYSBzaW1pbGFyIGRpcmVjdGlvbiBvZiBtaVJOQSBleHByZXNzaW9uICh3aGVuIGJveHBsb3RzIGFuZCByZWQgc3F1YXJlcyBzaG93IGNvbW1vbiBkb3ducmVndWxhdGlvbiBvciB1cHJlZ3VsYXRpb24sIHJlc3BlY3RpdmVseSkuIENvbnRyYWRpY3RvcnkgcmVzdWx0cyBhcmUgcHJlc2VudCBmb3IgbWlSTkEtNy01cCBpbiBTQ0MtMTIgKEZpcmVwbGV4OiB1cHJlZ3VsYXRlZCBxUENSOiBkb3ducmVndWxhdGVkKSwgZm9yIG1pUi0xMjYtM3AgaW4gU0NDLTEyIChGaXJlcGxleDogbm90IGNoYW5nZWQsIHFQQ1I6IHVwcmVndWxhdGVkKSBhbmQgU0NDLTEzIChGaXJlcGxleDogdXByZWd1bGF0ZWQsIHFQQ1I6IGRvd25yZWd1bGF0ZWQpLCBmb3IgbWlSLTEzNWItNXAgaW4gU0NDLTEzIChGaXJlcGxleDogdXByZWd1bGF0ZWQsIHFQQ1I6IG5vdCBjaGFuZ2VkKSwgZm9yIG1pUi0xNDYtNXAgaW4gU0NDLTEyIChGaXJlcGxleDogdXByZWd1bGF0ZWQsIHFQQ1I6IGRvd25yZWd1bGF0ZWQpIGFuZCBTQ0MtMTMgKEZpcmVwbGV4OiBkb3ducmVndWxhdGVkLCBxUENSOiB1cHJlZ3VsYXRlZCksIGZvciBtaVIgMjAwYS0zcCBpbiBTQ0wtSUkgKEZpcmVwbGV4OiB1cHJlZ3VsYXRlZCwgcVBDUjogZG93bnJlZ3VsYXRlZCkgYW5kIGZvciBtaVItNDI0LTVwIGluIFNDQy0xMyAoRmlyZXBsZXg6IHVwcmVndWxhdGVkLCBxUENSOiBkb3ducmVndWxhdGVkKSBhbmQgU0NMLUlJIChGaXJlcGxleDogdXByZWd1bGF0ZWQsIHFQQ1I6IG5vdCBjaGFuZ2VkKS4gVGhlIGJlc3Qgb3ZlcmxhcCBiZXR3ZWVuIEZpcmVwbGV4IGFuZCBxUENSIHJlc3VsdCBjb3VsZCBiZSBvYnNlcnZlZCBmb3IgbWlSLTIwNS01cCB3aXRoIHRoZSBsb2cyRkMgb2YgdGhlIEZpcmVwbGV4IGFuYWx5c2lzIGJlaW5nIHdpdGhpbiB0aGUgZGF0YSByYW5nZSBjb3ZlcmVkIGJ5IHRoZSBib3hwbG90IGZvciBlYWNoIGNlbGwgbGluZS4gQmVjYXVzZSBvZiB0aGlzIGNvbnNpc3RlbnQgZG93bnJlZ3VsYXRpb24gYW5kIHRoZSByb2xlIG9mIG1pUi0yMDUtNXAgaW4gY2FuY2VyIHByb2dyZXNzaW9uIGFuZCBtZXRhc3Rhc2lzIGluIHZhcmlvdXMgY2FuY2VyIGVudGl0aXRpZXMsIHRoZSByb2xlIG9mIHRoaXMgbWlSTkEgd2FzIGNob3NlbiB0byBiZSBmdXJ0aGVyIGVsdWNpZGF0ZWQgaW4gdGhlIGNvbnRleHQgb2YgY1NDQyBwcm9ncmVzc2lvbiAoc2VlIHNlY3Rpb24gMikuIA0KDQojIyAgMS41IFVWIHNlbnNpdGl2aXR5IG9mIGNlbGwgbGluZXMNCg0KQXMgaW5kaWNhdGVkIGluIHNlY3Rpb24gMS40LjIgdGhlcmUgd2VyZSBkaWZmZXJlbmNlcyBpbiB0aGUgVVYtcmVzcG9uc2l2ZW5lc3Mgb2YgZGlmZmVyZW50IGNlbGwgbGluZXMuIFRoaXMgcGhlbm9tZW5vbiB3YXMgbW9yZSB0aG9yb3VnaGx5IGludmVzdGlnYXRlZCBpbiB0aGlzIHNlY3Rpb24uIFRvIHRoaXMgZW5kIHRoZSBhYnNvbHV0ZSBmb2xkLWNoYW5nZSAodG8gYXZvaWQgbmVnYXRpdmUgYW5kIHBvc2l0aXZlIGZvbGQtY2hhbmdlcyBjYW5jZWxsaW5nIG91dCkgYmV0d2VlbiBpcnJhZGlhdGVkIGFuZCBjb250cm9sIGNlbGxzICBvZiBhbGwgbWlSTkFzIGJldHdlZW4gd2FzIGF2ZXJhZ2VkIGZvciBlYWNoIGNlbGwgbGluZSBhbmQgY29tcGFyZWQgKEZpZy4gMTQpLiANCg0KYGBge3J9DQojIGNvbnZlcnQgbG9nMi1mb2xkIGNoYW5nZXMgdG8gYWJzb2x1dGUgbG9nMi1mb2xkIGNoYW5nZXMNCmRhdF9VVl9zZW5zIDwtIGZvbGRzICU+JSANCiAgdW5ncm91cCgpJT4lIA0KICBtdXRhdGUoYWJzbG9nMkZDPSBhYnMobG9nMkZDKSkNCmBgYA0KDQpBcyB0aGUgZGF0YSB3YXMgYnkgZGVmaW5pdGlvbiBub3QgYWJsZSB0byBoYXZlIG5lZ2F0aXZlIHZhbHVlcywgbm9uLW5vcm1hbGl0eSB3YXMgYXNzdW1lZCBhbmQgbm9uLXBhcmFtZXRyaWMgdGVzdHMgd2VyZSB1c2VkIGZvciBzdGF0aXN0aWNhbCB0ZXN0aW5nIG9mIGRpZmZlcmVuY2VzIGJldHdlZW4gZ3JvdXBzLiANCg0KYGBge3IsIG1lc3NhZ2UgPSBGQUxTRX0NCiMgS3J1c2thbCBXYWxsaXMgdGVzdCB0byB0ZXN0IGlmIHRoZXJlIGFyZSBhbnkgZGlmZmVyZW5jZXMgYmV0ZWVuIGNlbGwgbGluZXMNCmRhdF9VVl9zZW5zICU+JSANCiAga3J1c2thbF90ZXN0KGFic2xvZzJGQ35jZWxsX2xpbmUpDQoNCiMgV2lsY294b24tTWFubi1XaGl0bmV5IFUgdGVzdCB0byBjb21wYXJlIGdyb3VwcyBwYWlyd2lzZQ0KZGF0X1VWX3NlbnMgJT4lIA0KICBkdW5uX3Rlc3QoYWJzbG9nMkZDfmNlbGxfbGluZSwgcC5hZGp1c3QubWV0aG9kID0gImZkciIpDQpgYGANCg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCiMgZGVmaW5lIHBvc2l0aW9uIGZvciBqaXR0ZXIgYW5kIHRleHQgbGFiZWxzDQpwb3MgPC0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMC4wNSwgc2VlZCA9IDIpDQoNCiMgZGVmaW5lIGxhYmVscyB0byBzaG93IHRoZSAzIG1vc3QgVVYtcmVzcG9uc2l2ZSBtaVJOQXMNCmxhYmVscyA8LSBkYXRfVVZfc2VucyAlPiUgDQogIGdyb3VwX2J5KGNlbGxfbGluZSkgJT4lDQogIHRvcF9uKDMsIGFic2xvZzJGQykgJT4lIA0KICBtdXRhdGUobGFiZWwgPSBtaVJOQSkNCg0KIyBtZXJnZSBkYXRhIHdpdGggbGFiZWxzDQpkYXRfbGFiZWxsZWQgPC0gbGVmdF9qb2luKGRhdF9VVl9zZW5zLGxhYmVscykgJT4lDQogIG11dGF0ZShsYWJlbCA9IGlmZWxzZShpcy5uYShsYWJlbCksICIiLCBsYWJlbCkpDQoNCiMgcGxvdA0KIyBhZGQgZXJyb3JiYXJzDQpwbG90X1VWX3NlbnMgPC0gZGF0X2xhYmVsbGVkICU+JSANCiAgZ2dwbG90KGFlcyhjZWxsX2xpbmUsYWJzbG9nMkZDKSkgKw0KICBzdGF0X2JveHBsb3QoDQogICAgZ2VvbSA9J2Vycm9yYmFyJywNCiAgICBzaXplPTAuNSwNCiAgICB3aWR0aCA9IDAuMg0KICApICsNCiAgIyBhZGQgYm94cGxvdA0KICBnZW9tX2JveHBsb3QoDQogICAgY29sb3IgPSAiYmxhY2siLA0KICAgIG1hcHBpbmcgPSBhZXMoeCA9IGNlbGxfbGluZSx5ID0gYWJzbG9nMkZDKSwNCiAgICBvdXRsaWVyLnNoYXBlID1OQSwNCiAgICB3aWR0aD0wLjQNCiAgKSArDQogICMgYWRkIHBvaW50cyB0byBkaXNwbGF5IGVhY2ggaW5kaXZpZHVhbCBtaVJOQQ0KICBnZW9tX2ppdHRlcigNCiAgICBkYXRhID0gIGZpbHRlcihkYXRfbGFiZWxsZWQsIGxhYmVsID09ICIiKSwNCiAgICBtYXBwaW5nID0gYWVzKHggPSBjZWxsX2xpbmUseSA9IGFic2xvZzJGQyksDQogICAgd2lkdGg9MC4xLA0KICAgIGFscGhhPTAuMw0KICApICsNCiAgIyBsYWJlbCB0aGUgdG9wIDMgY2hhbmdlZCBtaVJOQXMgd2l0aCByZWRzDQogIGdlb21faml0dGVyKA0KICAgIGRhdGEgPSAgZmlsdGVyKGRhdF9sYWJlbGxlZCwgbGFiZWwgIT0gIiIpLA0KICAgIG1hcHBpbmcgPSBhZXMoeCA9IGNlbGxfbGluZSx5ID0gYWJzbG9nMkZDLCBmaWxsID0gInJlZCIpLA0KICAgIHNoYXBlID0gMjEsIA0KICAgIGNvbG91ciA9ICJibGFjayIsDQogICAgcG9zaXRpb24gPSBwb3MNCiAgKSArIA0KICAjIHNob3cgdGV4dCBsYWJlbCBvZiB0aGUgdG9wIDMgY2hhbmdlZCBtaVJOQXMNCiAgZ2VvbV90ZXh0X3JlcGVsKA0KICAgIGRhdGEgPSAgZmlsdGVyKGRhdF9sYWJlbGxlZCwgbGFiZWwgIT0gIiIpLA0KICAgIG1hcHBpbmcgPSBhZXMoeCA9IGNlbGxfbGluZSwgeSA9IGFic2xvZzJGQywgbGFiZWwgPSBsYWJlbCksDQogICAgc2l6ZSA9IDMsDQogICAgcG9zaXRpb24gPSBwb3MNCiAgKSArIA0KICB0aGVtZV9QaEQoTGVnZW5kPUYpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9OTAsIHZqdXN0PSAwLjQsIGhqdXN0PSAxKSkgKw0KICB5bGFiKCJhYnNvbHV0ZSBsb2cyLUZDIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDMuMyksIGJyZWFrcyA9IHNlcSgwLDMsMC41KSkNCmBgYA0KIVsqKkZpZy4gMTQ6IFVWLXNlbnNpdGl2aXR5IG9mIGNlbGwgbGluZXMuKiogVGhlIHRocmVlIG1vc3QgVVYtcmVzcG9uc2l2ZSBtaVJOQXMgYXJlIHNob3duIGluIHJlZCB3aXRoIG5hbWUgbGFiZWxzLiBuID0gNDAuIF0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL01CZW5kZXIxOTkyL1BoRC9NYXJjL1Jlc3VsdHMvVVZfc2Vuc2l0aXZpdHkucG5nKQ0KDQoNClNDQy0xMiBhbmQgU0NDLTEzIHNob3cgc2lnbmlmaWNhbnRseSBoaWdoZXIgYWJzb2x1dGUgbG9nMkZDIGluZGljYXRpbmcgYSBoaWdoZXIgVVYtcmVzcG9uc2l2ZW5lc3Mgb2YgdGhlc2UgY2VsbCBsaW5lcy4gQWx0aG91Z2ggbm90IHNpZ25pZmljYW50bHkgY2hhbmdlZCwgU0NMLUlJIGFsc28gc2hvd3MgaGlnaGVyIFVWLXNlbnNpdGl2aXR5IHRoYW4gTWV0LTEgYW5kIE1ldC00LiBUaGVyZSBhcmUgbWlub3IgZGlmZmVyZW5jZXMgYmV0d2VlbiBjZWxsIGxpbmVzIGluIHJlc3BlY3QgdG8gd2hpY2ggbWlSTkFzIGFyZSBhbHRlcmVkIHRoZSBtb3N0IGFmdGVyIFVWIGlycmFkaWF0aW9uLCBob3dldmVyIG1pUi01MDMtNXAsIG1pUi0xNDZhLTVwIGFuZCBtaVItMzBhLTNwIGV4aGliaXQgdGhlIGhpZ2hlc3QgZGlmZmVyZW5jZXMgaW4gYWxtb3N0IGFsbCBjZWxsIGxpbmVzLiBUaGUgbG93ZXIgVVYtcmVzcG9uc2UgaW4gTWV0LTEgYW5kIE1ldC00IG1pZ2h0IGJlIGR1ZSB0byBhIGZ1bmN0aW9uYWwgcDUzIHByb3RlaW4gYW5kIGJldHRlciBETkEgZGFtYWdlIHJlc3BvbnNlLg0KDQojIDIgbWlSTkEgZXhwcmVzc2lvbiBpbiBjU0NDIHRpc3N1ZQ0KDQpUbyBpZGVudGlmeSBwb3NzaWJsZSBtaVJOQXMgd2l0aCBvbmNvZ2VuaWMgZnVuY3Rpb24gaW4gY1NDQyB3aGljaCBhcmUgaW5kdWNlZCBieSBVVi1yYWRpYXRpb24gd2UgY29tcGFyZWQgdGlzc3VlIHNhbXBsZXMgb2YgcGF0aWVudHMgd2l0aCBjU0NDIChuID0gNSkgd2l0aCBza2luIGJpb3BzaWVzIG9mIGhlYWx0aHkgZG9ub3JzIGZyb20gc3VuLWV4cG9zZWQobiA9IDUpIGFuZCBzdW4tcHJvdGVjdGVkIChuID0gNikgYXJlYXMuIEFsdGhvdWdoIHRoZXJlIHdlcmUgbm8gZXZpZGVudCBkaWZmZXJlbmNlcyBiZXR3ZWVuIHN1bi1wcm90ZWN0ZWQgYW5kIHN1bi1leHBvc2VkIHNraW4gdGhlIGNTQ0MgdGlzc3VlIHdhcyBjbGVhcmx5IHNlcGFyYXRlZCBpbiBhIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nIGFuYWx5c2lzIChGaWcuIDE1QSkuIFR3byBkaXN0aW5jdCBjbHVzdGVycyBzaG93ZWQgbWlSTkFzIG92ZXJleHByZXNzZWQgaW4gdHVtb3IgdGlzc3VlIChDbHVzdGVyIDFBKSBhbmQgc3VwcHJlc3NlZCBpbiB0dW1vciB0aXNzdWUgKENsdXN0ZXIgNEEpLiBUaGUgbWlSTkFzIGluIENsdXN0ZXIgMUEgYXJlIHdlbGwga25vd24gb25jby1taVJzIHdoaWNoIGFyZSBvdmVyZXhwcmVzc2VkIGluIHZhcmlvdXMgdHVtb3JzLiBHZW5lcyB0YXJnZXRlZCBieSBhbGwgMyBtaVJOQXMgYXJlIHNob3duIGluIEZpZy4gMTVCLiBBIHBhdGh3YXkgYW5hbHlzaXMgY29uZHVjdGVkIHdpdGggdGhlIFIgcGFja2FnZSBSQmlvbWlSR1MgaW5jb3Jwb3JhdGluZyBhbGwga25vd24gKGV4cGVyaW1lbnRhbGx5IHZhbGlkYXRlZCkgdGFyZ2V0cyBvZiB0aGUgbWlSTkEgdHJpcGxldCByZXZlYWxlZCBvbmx5IG9uZSBwYXRod2F5IChLRUdHX0FYT05fR1VJREFOQ0UpIHRvIGJlIG92ZXJyZXByZXNlbnRlZCBpbiB0aGUgZ2VuZSBzZXQgKEZpZy4gMTVEKS4gVGhpcyBpcyBtb3N0IGxpa2VseSBkdWUgdG8gdGhlIGxvdyBudW1iZXIgb2YgbWlSTkFzIGFuZCB0aGVyZWZvcmUgYSBsb3cgbnVtYmVyIG9mIHRhcmdldCBnZW5lcy4gT24gdGhlIG90aGVyIGhhbmQgdGhlIGdlbmVzIHRhcmdldGVkIGJ5IGF0IGxlYXN0IDcgbWlSTkFzIG9mIGRvd25yZWd1bGF0ZWQgbWlSTkFzIGluIGNTQ0MgdGlzc3VlIGFyZSBzaG93biBpbiBGaWcuIDE1QyBhbmQgYSBwYXRod2F5IGFuYWx5c2lzIHJldmVhbGVkIHRoZSBhY3RpdmF0aW9uIG9mIHBhdGh3YXlzIGxpa2UgS0VHR19FUkJCX1NJR05BTElOR19QQVRIV0FZIG9yIEtFR0dfTUFQS19TSUdOQUxJTkdfUEFUSFdBWSBpbmRpY2F0aW5nIGFjdGl2YXRpb24gb2YgZ3Jvd3RoIHJlbGF0ZWQgc2lnbmFsaW5nIHBhdGh3YXlzIGluIHR1bW9yIHRpc3N1ZS4gDQoNCkEgc2Vjb25kIHBhdGh3YXkgYW5hbHlzaXMgdG9vbCAobWlSVGFyZ2V0bGluayAyLjApIHlpZWxkZWQgc2ltaWxhciByZXN1bHRzIHdpdGggZXZlbiBtb3JlIHR1bW9yIHJlbGF0ZWQgcGF0aHdheXMgb3ZlcnJlcHJlc2VudGVkIGluIHRoZSBnZW5lIHNldCB0YXJnZXRlZCBieSB0aGUgbWlSTkFzIGluIENsdXN0ZXIgNEEuIE9uIHRvcCBvZiBncm93dGggcmVsYXRlZCBwYXRod2F5cyB0aGVyZSBhcmUgYWxzbyBvdGhlciB0dW1vciBhc3NvY2lhdGVkIHBhdGh3YXlzIGxpa2UgS0VHR19WRUdGX1NJR05BTElOR19QQVRIV0FZIChhbmdpb2dlbmVzaXMpIG9yIEtFR0dfQURIRVJFTlNfSlVOQ1RJT04gYW5kIEtFR0dfRk9DQUxfQURIRVNJT04gKG1pZ3JhdGlvbikgdGhhdCB3ZXJlIGVucmljaGVkIChpbiB0aGUgdG9wIDIwKSB1c2luZyB0aGlzIHdlYnRvb2wuIA0KSW4gdGhlIHRvcCAyMCBlbnJpY2hlZCBHTyB0ZXJtcyBpdCB3YXMgZXZpZGVudCB0aGF0IHRoZSBiaW9sb2dpY2FsIGZ1bmN0aW9uIG9mIHRoZXNlIG1pUk5BcyBpcyBjbG9zZWx5IHJlbGF0ZWQgdG8gdGhlIHJlc3BvbnNlIHRvIChVVikgcmFkaWF0aW9uIGFuZCBncm93dGggcmVsYXRlZCBzaWduYWxpbmcgcGF0aHdheXMuIA0KDQpJbiBzdW1tYXJ5IHRoZSBtaVJOQSBleHByZXNzaW9uIGJldHdlZW4gdHVtb3IgdGlzc3VlIGFuZCBza2luICh3aXRob3V0IGRpZmZlcmVuY2VzIGJldHdlZW4gc3VuLWV4cG9zZWQgb3Igc3VuLXByb3RlY3RlZCBhcmVhcykgaXMgdmVyeSBkaXN0aW5jdCBmb3IgY2VydGFpbiBtaVJOQXMgd2l0aCBhIHN1YnNldCBvZiBkb3ducmVndWxhdGVkIG1pUk5BcyBpbiB0dW1vciB0aXNzdWUgaW52b2x2ZWQgaW4gY2VsbCBncm93dGgsIGNlbGwgbWlncmF0aW9uLCB0dW1vciBwcm9ncmVzc2lvbiBhbmQgdGhlIHJlc3BvbnNlIHRvIFVWIHJhZGlhdGlvbi4gVGhpcyBpbmRpY2F0ZXMgdGhhdCAtIGFsdGhvdWdoIG5vdCBhbHRlcmVkIGluIHN1bi1leHBvc2VkIHNraW4gLSB0aGVzZSBtaVJOQXMgYXJlIGFzc29jaWF0ZWQgdG8gYSBjaHJvbmljIGFuZCBpbiB0aGUgZW5kIGZhaWxlZCByZXNwb25zZSB0byBnZW5vdG94aWMgc3RyZXNzIGV4ZXJ0ZWQgYnkgVVYtcmFkaWF0aW9uLiANCg0KVGFrZW4gdG9nZXRoZXIgd2l0aCB0aGUgZmluZGluZ3Mgb2J0YWluZWQgKmluIHZpdHJvKiB0aGVyZSB3YXMgb25seSBvbmUgbWlSTkEgdGhhdCBpcyBkb3ducmVndWxhdGVkIGluIGNTQ0MgdGlzc3VlIGFzIHdlbGwgYXMgc3Vic2VxdWVudCB0byBjaHJvbmljIFVWIHJhZGlhdGlvbiBpbiBhbGwgNSBjZWxsIGxpbmVzOiBtaVJOQS0yMDUuIFRoaXMgbWlSTkEgbWlnaHQgcGxheSBhIGNydWNpYWwgcm9sZSBpbiB0aGUgVVYtaW5kdWNlZCBjYXJjaW5vZ2VuZXNpcyBvZiBjU0NDLiBUbyBleGFtaW5lIHRoZSBlZmZlY3RzIG9mIG1pUi0yMDUgb24gYSBtZWNoYW5pc3RpYyBsZXZlbCB3ZSBwZXJmb3JtZWQgKmluIHZpdHJvKiBrbm9ja2Rvd24gZXhwZXJpbWVudHMgYW5kIGludmVzdGlnYXRlZCBlbmRwb2ludHMgbGlrZSBjZWxsIGdyb3d0aCwgY2VsbCBjeWxjZSBkaXN0cmlidXRpb24sIGFwb3B0b3NpcywgbWlncmF0aW9uLCBpbnZhc2lvbiBhcyB3ZWxsIGFzIGV4cHJlc3Npb24gb2YgcHJvbWluZW50IHR1bW9yIGFzc29jaWF0ZWQgZ2VuZXMgdGFyZ2V0ZWQgYnkgbWlSLTIwNS4NCg0KDQohWyoqRmlnLiAxNTogbWlSTkEgZXhwcmVzc2lvbiBpbiBjU0NDIHRpc3N1ZSBjb21wYXJlZCB0byBzdW4tZXhwb3NlZCBhbmQgc3VuLXByb3RlY3RlZCBza2luLioqIEE6IEhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nIGFuYWx5c2lzIG9mIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBtaVJOQXMgaW4gY1NDQyB0aXNzdWUuIEI6IE5ldHdvcmsgYW5hbHlzaXMgb2YgbWlSTkFzIG92ZXJleHByZXNzZWQgaW4gY1NDQyB0aXNzdWUuIEM6IE5ldHdvcmsgYW5hbHlzaXMgb2YgbWlSTkFzIHN1cHByZXNzZWQgaW4gY1NDQyB0aXNzdWUuIEQ6IFBhdGh3YXkgYW5hbHlzaXMgbWlSTkEgdGFyZ2V0cyBzaG93biBpbiBCIGdlbmVyYXRlZCB3aXRoIEJpb21pUkdTLiBFOiBQYXRod2F5IGFuYWx5c2lzIG9mIG1pUk5BIHRhcmdldHMgc2hvd24gaW4gQy4gXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vTUJlbmRlcjE5OTIvUGhEL01hcmMvUmVzdWx0cy90aXNzdWVfY1NDQ19taVJOYXNfcGF0aHdheS5wbmcpDQoNCiMgMyBLbm9ja2Rvd24gb2YgbWlSLTIwNS01cA0KDQojIyAzLjEgVGVzdGluZyB0cmFuc2ZlY3Rpb24gY29uZGl0aW9ucw0KDQpUbyBhc3Nlc3MgS25vY2tkb3duIGVmZmljaWVuY3ksIFNDQy0xMiBjZWxscyB3ZXJlIHNlZWRlZCBhdCA0MC4wMDAgY2VsbHMgcGVyIHdlbGwgaW4gYSAyNC13ZWxsIFBsYXRlLCBpbmN1YmF0ZWQgZm9yIDI0IGggaW4gc3RhbmRhcmQgY2VsbCBjdWx0dXJlIGNvbmRpdGlvbnMgYW5kIHRyYW5zZmVjdGVkIHdpdGggZGlmZmVyZW50IGNvbmNlbnRyYXRpb25zIG9mIGFudGFnb21pci0yMDUgb3IgYSBjb250cm9sIG9saWdvIHVzaW5nIHRoZSBIaVBlcmZlY3QgVHJhbnNmZWN0aW9uIFJlYWdlbnQgKFFpYWdlbikuIENlbGxzIHdlcmUgaGFydmVzdGVkIDI0IGggYW5kIDcyIGggYWZ0ZXIgdHJhbnNmZWN0aW9uLCBSTkEgd2FzIGlzb2xhdGVkIGFuZCBtaVItMjA1IGV4cHJlc3Npb24gd2FzIHF1YW50aWZpZWQgdmlhIHFQQ1IuIFRoZSByZXN1bHRzIGFyZSBzaG93biBpbiBmaWd1cmUgMTUuIA0KDQoNCmBgYHtyLCBldmFsID0gRkFMU0V9DQojIGxvYWQgYW5kIHRyYW5zZm9ybSBkYXRhDQpkYXRfcVBDUiA8LSByZWFkX2NzdigiRGF0YS9QaERfTUJfcVBDUl90cmFuc2ZlY3Rpb25fbWlyXzIwNV8yMDIxMDQyNy5jc3YiKSU+JSANCiAgcmVuYW1lKE5hbWUgPSBQcm9iZW5uYW1lKSAlPiUNCiAgbXV0YXRlKHRpbWUgPSBzdHJfZXh0cmFjdCguJE5hbWUsICJcXGQraCIpKSAlPiUNCiAgbXV0YXRlKHRyZWF0bWVudCA9IHN0cl9yZXBsYWNlX2FsbCguJE5hbWUsICJfLiskIiwiIikpICU+JQ0KICBtdXRhdGUoY29uZGl0aW9uID0gc3RyX2V4dHJhY3QoLiROYW1lLCAiXFxkK25NLittaWNyb0wiKSkNCg0KZGF0X21pbWljIDwtIGRhdF9xUENSICU+JSBmaWx0ZXIodHlwZSA9PSAibWltaWMiKQ0KZGF0X2FudGFnbyA8LSBkYXRfcVBDUiAlPiUgZmlsdGVyKHR5cGUgPT0gImFudGFnbyIpDQoNCiMjIGFudGFnbyBtaXIgDQpkZENUX2FudGFnbyA8LSBnZXRfZGRDVChkYXRfYW50YWdvLCBJRCA9ICJOYW1lIiwgZ3JvdXAuY3RybCA9ICJ0aW1lIiwgY3QudmFsID0gIm1lYW5fY3QiKSAlPiUNCiAgbXV0YXRlKGNvbmRpdGlvbiA9IGZhY3Rvcihjb25kaXRpb24sIGxldmVscyA9IGMoIjVuTV8xLjVtaWNyb0wiLCAiNW5NXzNtaWNyb0wiLCAiMTBuTV8zbWljcm9MIiwgIjUwbk1fM21pY3JvTCIpKSkNCg0KZGRDVF9hbnRhZ28gJT4lDQogIGdncGxvdChhZXModGltZSwgZGRDVCwgZmlsbCA9IGZhY3Rvcihjb25kaXRpb24pKSkgKw0KICBnZW9tX2Vycm9yYmFyKHN0YXQgPSAic3VtbWFyeSIsIGZ1bi5kYXRhID0gIm1lYW5fc2RsIiwgZnVuLmFyZ3MgPSBsaXN0KG11bHQgPSAxKSwNCiAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC40OCksIHdpZHRoID0gMC4yNSwgc2l6ZSA9IDAuNikrDQogIGdlb21fYmFyKHN0YXQgPSAic3VtbWFyeSIsIGZ1biA9ICJtZWFuIiwNCiAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNDgpLA0KICAgICAgICAgICBtYXBwaW5nID0gYWVzKHggPSB0aW1lLHkgPSBkZENUKSwNCiAgICAgICAgICAgd2lkdGg9MC40DQogICkgICsgDQogIGdlb21faGxpbmUoeWludGVyY2VwdD0gMCwgbHR5ID0gMikgKw0KICB0aGVtZV9QaEQoYXhpcy50ZXh0LnNpemUgPSAxMCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICkgKyANCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTQsMiksIGJyZWFrcyA9IHNlcSgtNCwyLDEpKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiR3JleXMiKQ0KYGBgDQohWyoqRmlnLiAxNjogVGVzdGluZyBvZiBkaWZmZXJlbnQgbWlSLTIwNSBLbm9ja2Rvd24gY29uZGl0aW9ucy4qKiBEYXRhIHdlcmUgbm9ybWFsaXplZCB0byB0aGUgZ2VvbWV0cmljIG1lYW4gb2YgbWlSLTE2LCBzbm80NCBhbmQgc25vNDggZXhwcmVzc2lvbi4gXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vTUJlbmRlcjE5OTIvUGhEL01hcmMvUmVzdWx0cy9BbnRhZ29fbWlSLTIwNV9xUENSX2NvbmRpdGlvbnNfbGVnZW5kLnBuZykNCg0KDQojIyAzLjIgZ3Jvd3RoIGFuYWx5c2lzDQoNCiFbKipGaWcuIDE3OiBUaXRsZS4qKiBUZXh0IF0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL01CZW5kZXIxOTkyL1BoRC9NYXJjL1Jlc3VsdHMvLnBuZykNCg0KIyMgMy4zIGNlbGwgY3ljbGUgZGlzdHJpYnV0aW9uDQoNCiFbKipGaWcuIDE4OiBDZWxsIGN5Y2xlIGRpc3RyaWJ1dGlvbiBvZiBtaVItMjA1IEtub2NrZG93biBhbmQgY29udHJvbCB0cmFuc2ZlY3RlZCBjZWxscy4qKiBBOiBDZWxsIGN5Y2xlIGRpc3RyaWJ1dGlvbiBvZiBjb250cm9sIHRyYW5zZmVjdGVkIGNlbGxzLiBCOiBDZWxsIGN5Y2xlIGRpc3RyaWJ1dGlvbiBvZiBjZWxscyB0cmFuc2ZlY3RlZCB3aXRoIGFudGFnb21pci0yMDUuIEM6IEJhcnBsb3Qgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBvZiBHMSwgUyBhbmQgRzIgcGhhc2UgaW4gdGhlIGRpZmZlcmVudGx5IHRyZWF0ZWQgY2VsbHMgYXQgZGlmZmVyZW50IHRpbWVwb2ludHMuICBdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9NQmVuZGVyMTk5Mi9QaEQvTWFyYy9SZXN1bHRzL2NlbGxfY3ljbGVfZGlzdHJpYnV0aW9uX2NvbWJpbmVkLnBuZykNCg0KIyA0IFRHRiBiZXRhDQoNClRoZSBrbm9ja2Rvd24gZXhwZXJpbWVudHMgd2l0aCBzb2xlbHkgbWlSLTIwNSBkaWQgbm90IHNob3cgYW55IGRpZmZlcmVuY2VzIGluIHBoZW5vdHlwZXMgb2YgY29udHJvbCBvciB0cmFuc2ZlY3RlZCBjZWxscywgYWx0aG91Z2ggbWlSLTIwNSB3YXMgc3RhYmx5IGRvd25yZWd1bGF0ZWQuIEhvd2V2ZXIgdGFyZ2V0IGdlbmVzIHdlcmUgb25seSB1cHJlZ3VsYXRlZCAyNGggcG9zdCB0cmFuc2ZlY3Rpb24gYW5kIGV2ZW4gc2hvd2VkIGRvd25yZWd1bGF0aW9uIDcyaCBwb3N0IHRyYW5zZmVjdGlvbiB3aXRoIGEgbm9ybWFsaXphdGlvbiBvZiBnZW5lIGV4cHJlc3Npb24gMTQ0aCBwb3N0ICB0cmFuc2ZlY3Rpb24uIFRoaXMgaW5kaWNhdGVzIGEgbmVnYXRpdmUgZmVlZGJhY2sgbWVjaGFuaXNtIHRoYXQgZW5zdXJlcyBjZWxsIGhvbWVvc3Rhc2lzLiBNb3Jlb3ZlciBpdCBpcyBrbm93biB0aGF0IGNhbmNlciBpcyBvcmNoZXN0cmF0ZWQgYnkgYSBtdWx0aXR1ZGUgb2YgcG90ZW50aWFsbHkgY2FyY2lub2dlbmljIGV2ZW50cyAtIGVhY2ggb2YgaXRzIG93biBub3Qgc3VmZmljaWVudCBmb3IgdHVtb3JpZ2VuZXNpcyAtIHdoaWNoIGluIHN1bSBsZWFkIHRvIGNhbmNlciBmb3JtYXRpb24gYW5kIHByb2dyZXNzaW9uLiBXZSB0aGVyZWZvcmUgc3BlY3VsYXRlZCB0aGF0IG1pUi0yMDUgc3VwcHJlc3Npb24gYWxvbmUgaXMgbm90IHN1ZmZpY2llbnQgdG8gaW5jcmVhc2UgbWlncmF0aW9uIG9yIGludmFzaW9uIHByb2Nlc3NlcyBjb25uZWN0ZWQgdG8gRU1UICh3aGljaCBpcyBhIGNydWNpYWwgcHJvY2VzcyBvbiB0aGUgd2F5IHRvIG1ldGFzdGFzZXMpLiBJbmRlZWQgaXQgd2FzIHNob3duIHRoYXQgbWlSLTIwNSByZWd1bGF0ZXMgRU1UIHRvZ2V0aGVyIHdpdGggVEdGLWJldGEsIHdoZXJlIG1pUi0yMDUgc3VwcHJlc3NlcyBFTVQgYW5kIFRHRi1iZXRhIGluZHVjZXMgRU1ULiBGdXJ0aGVybW9yZSBUR0YtYmV0YSBpcyB1cHJlZ3VsYXRlZCBmb2xsb3dpbmcgVVYgaXJyYWRpYXRpb24gYW5kIGFsc28gZnJlcXVlbnRseSB1cHJlZ3VsYXRlZCBpbiBjU0NDIHR1bW9ycy4gVGhlcmVmb3JlIGl0IGlzIGxpa2VseSB0aGF0IG92ZXJleHByZXNzaW9uIG9mIFRHRi1iZXRhIGluIGNvLW9wZXJhdGlvbiB3aXRoIGRvd25yZWd1bGF0aW9uIG9mIG1pUi0yMDUgaW5kdWNlcyBFTVQgaW4gYSBzeW5lcmdpc3RpYyBwcm9jZXNzLiANCg0KVG8gdGVzdCB0aGlzIGh5cG90aGVzaXMgdGhlIGRpZmZlcmVudCBlbmRwb2ludCBhbmFseXNpcyBvZiBzZWN0aW9uIDMgd2VyZSByZXBlYXRlZCBhbmQgdHdvIGFkZGl0aW9uYWwgdHJlYXRtZW50IG9wdGlvbnMgd2VyZSBleGFtaW5lZC4gKGNvbnRyb2wsIFRHRmIrLCBtaVItMjA1LSwgVEdGYisgdW5kIG1pUi0yMDUtKQ0KDQoNCg0KDQoNCg==